78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
# 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) |