Initial commit

This commit is contained in:
Abdulaziz Axmadaliyev
2026-02-26 16:35:47 +05:00
commit 92165edbe6
2984 changed files with 629155 additions and 0 deletions

0
app/api/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

0
app/api/health.py Normal file
View File

45
app/api/payme.py Normal file
View File

@@ -0,0 +1,45 @@
from fastapi import APIRouter, Request, Depends
from sqlalchemy.orm import Session
from app.db.session import get_db
from app.core.security import verify_payme_auth
from app.services.payme_service import (
check_perform_transaction,
create_transaction_handler,
perform_transaction_handler,
cancel_transaction_handler,
)
router = APIRouter()
@router.post("/payme")
async def payme_webhook(
request: Request,
db: Session = Depends(get_db),
_: None = Depends(verify_payme_auth),
):
body = await request.json()
method = body.get("method")
params = body.get("params", {})
request_id = body.get("id")
if method == "CheckPerformTransaction":
result = await check_perform_transaction(params)
elif method == "CreateTransaction":
result = await create_transaction_handler(db, params)
elif method == "PerformTransaction":
result = await perform_transaction_handler(db, params)
elif method == "CancelTransaction":
result = await cancel_transaction_handler(db, params)
else:
return {
"jsonrpc": "2.0",
"id": request_id,
"error": {"code": -32601, "message": "Method not found"},
}
return {
"jsonrpc": "2.0",
"id": request_id,
"result": result,
}

78
app/api/shopify.py Normal file
View File

@@ -0,0 +1,78 @@
# app/api/shopify.py
import json
import base64
import hmac
import hashlib
from fastapi import APIRouter, Request, HTTPException
from app.core.config import settings
router = APIRouter()
def create_payme_payment_link(order_id: str, amount_uzs: float) -> str:
"""Generate a Payme checkout URL"""
# Amount must be in tiyin (1 UZS = 100 tiyin)
amount_tiyin = int(amount_uzs * 100)
# Payme requires account params to be base64-encoded
import json
account = json.dumps({"order": str(order_id)})
account_encoded = base64.b64encode(account.encode()).decode()
merchant_id = settings.PAYME_MERCHANT_ID
# Payme checkout URL format
params = f"m={merchant_id};ac.order={order_id};a={amount_tiyin}"
params_encoded = base64.b64encode(params.encode()).decode()
return f"https://checkout.paycom.uz/{params_encoded}"
@router.post("/shopify/order-created")
async def order_created(request: Request):
raw_body = await request.body()
# Verify Shopify webhook signature
hmac_header = request.headers.get("X-Shopify-Hmac-Sha256")
computed_hmac = base64.b64encode(
hmac.new(
settings.SHOPIFY_WEBHOOK_SECRET.encode(),
raw_body,
hashlib.sha256
).digest()
).decode()
if not hmac.compare_digest(computed_hmac, hmac_header or ""):
raise HTTPException(status_code=401, detail="Invalid webhook")
data = json.loads(raw_body)
order_id = str(data["id"])
total_price = float(data["total_price"])
customer_email = data.get("email", "")
# Generate Payme payment link
payment_link = create_payme_payment_link(order_id, total_price)
# Add the link as an order note in Shopify so customer can see it
await add_payment_link_to_order(order_id, payment_link)
return {"status": "payment_link_created", "link": payment_link}
async def add_payment_link_to_order(order_id: str, payment_link: str):
"""Add payment link as a note on the Shopify order"""
import httpx
url = f"https://{settings.SHOPIFY_STORE_URL}/admin/api/2024-01/orders/{order_id}.json"
headers = {
"X-Shopify-Access-Token": settings.SHOPIFY_ACCESS_TOKEN,
"Content-Type": "application/json",
}
payload = {
"order": {
"id": order_id,
"note": f"Payme payment link: {payment_link}"
}
}
async with httpx.AsyncClient() as client:
await client.put(url, json=payload, headers=headers)