Ana içeriğe geç

Python Entegrasyon Örneği

Bu rehber Python tabanlı servislerde MuditaKurye entegrasyonunu hızla hayata geçirmeniz için hazırlanmıştır. Örnekler requests ile sipariş oluşturma ve Flask ile webhook alma senaryolarını içerir.

Ön Koşullar

  • Python 3.10 veya üzeri
  • pip, venv erişimi
  • MuditaKurye tarafından sağlanan kimlik bilgileri
python -m venv .venv
source .venv/bin/activate
pip install requests flask python-dotenv gunicorn

Ortak Yapılandırma

.env dosyasıyla gizli bilgileri saklayın.

MUDITAKURYE_BASE_URL=https://api.muditakurye.com.tr
MUDITAKURYE_API_KEY=yk_sizin_api_anahtariniz
MUDITAKURYE_RESTAURANT_ID=rest_xxxxx
MUDITAKURYE_WEBHOOK_SECRET=whsec_xxxxx

settings.py dosyası:

from dataclasses import dataclass
import os


@dataclass(frozen=True)
class Settings:
    base_url: str = os.getenv("MUDITAKURYE_BASE_URL", "https://api.muditakurye.com.tr")
    api_key: str = os.getenv("MUDITAKURYE_API_KEY", "")
    restaurant_id: str = os.getenv("MUDITAKURYE_RESTAURANT_ID", "")
    webhook_secret: str = os.getenv("MUDITAKURYE_WEBHOOK_SECRET", "")


settings = Settings()

Sipariş Gönderme

scripts/create_order.py dosyası:

from __future__ import annotations

import json
import uuid
from typing import Any

import requests

from settings import settings


def create_order() -> dict[str, Any]:
    order_id = f"ext_{uuid.uuid4()}"
    payload = {
        "orderId": order_id,
        "restaurantId": settings.restaurant_id,
        "customerName": "Ayşe Demir",
        "customerPhone": "+905321234567",
        "deliveryAddress": "Bağdat Caddesi No: 456, Kadıköy, İstanbul",
        "paymentMethod": "CARD_POS",
        "paymentCaptured": False,
        "total": 189.9,
        "currency": "TRY",
        "items": [
            {
                "productCode": "BURGER_DOUBLE",
                "productName": "Double Burger Menü",
                "quantity": 1,
                "unitPrice": 159.9,
                "totalAmount": 159.9,
                "productNote": "Soğan olmasın",
            },
            {
                "productCode": "FRIES_LARGE",
                "productName": "Büyük Patates",
                "quantity": 1,
                "unitPrice": 30,
                "totalAmount": 30,
            },
        ],
        "notes": "Teslimattan 5 dk önce arayın",
    }

    response = requests.post(
        f"{settings.base_url}/webhook/third-party/order",
        headers={
            "X-API-Key": settings.api_key,
            "Content-Type": "application/json",
        },
        data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
        timeout=5,
    )
    response.raise_for_status()

    data = response.json()
    print("Sipariş oluşturuldu:", data)
    return data


if __name__ == "__main__":
    try:
        create_order()
    except requests.HTTPError as http_error:
        print("[MuditaKurye] HTTP hatası", http_error.response.status_code, http_error.response.text)
    except requests.RequestException as req_error:
        print("[MuditaKurye] Ağ hatası", req_error)

Flask Webhook Sunucusu

webhook_app.py dosyası:

from __future__ import annotations

import hashlib
import hmac
from typing import Any

from flask import Flask, request, jsonify

from settings import settings

app = Flask(__name__)


def verify_signature(raw_body: bytes, signature: str | None) -> bool:
    if not settings.webhook_secret:
        return True
    if not signature:
        return False

    computed = hmac.new(
        key=settings.webhook_secret.encode("utf-8"),
        msg=raw_body,
        digestmod=hashlib.sha256,
    ).hexdigest()

    return hmac.compare_digest(computed, signature)


@app.post("/webhook/muditakurye/status")
def handle_status() -> tuple[dict[str, Any], int]:
    raw_body = request.get_data()
    signature = request.headers.get("X-MuditaKurye-Signature")

    if not verify_signature(raw_body, signature):
        app.logger.warning("Geçersiz imza")
        return {"error": "invalid signature"}, 401

    payload = request.get_json(force=True, silent=False)
    event = payload.get("event")
    order_id = payload.get("orderId")
    status = payload.get("status")
    timestamp = payload.get("timestamp")

    app.logger.info("Webhook alındı event=%s orderId=%s status=%s time=%s", event, order_id, status, timestamp)

    # İş mantığınızı burada yürütün (örn. siparişi güncelle, ERP entegrasyonu, vb.)

    return jsonify({"received": True}), 200


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=3000, debug=True)

Çalıştırma

# Webhook sunucusunu başlatın
python webhook_app.py

# Yeni terminalde sipariş oluşturun
python scripts/create_order.py

Geliştirme ortamında webhook'u test etmek için:

ngrok http 3000

Gunicorn ile Prod Hazırlığı

gunicorn --bind 0.0.0.0:3000 --workers 2 webhook_app:app

Hata Yönetimi

  • response.raise_for_status() HTTP hatalarını yakalamanızı sağlar.
  • requests için backoff kütüphanesiyle retry ekleyebilirsiniz.
  • Webhook işlemede kritik hataları loglayıp Sentry veya New Relic gibi araçlara gönderin.

Test Önerileri

  1. Happy Path: Sipariş gönderin, webhook alın.
  2. Hatalı İmza: Yanlış X-MuditaKurye-Signature başlığıyla 401 dönüldüğünü doğrulayın.
  3. Tekrarlayan Webhook: Aynı payload'ı iki kez gönderip idempotent iş mantığını test edin.

Sonraki Adımlar

  • examples/nodejs.md ve examples/curl.md sayfalarındaki örneklerle kıyaslama yapın.
  • best-practices.md kısmındaki güvenlik ve izleme önerilerini uygulayın.
  • support.md sayfasındaki destek kanallarını proje ekibinizle paylaşın.