Ana içeriğe geç

Node.js Entegrasyon Örneği

Bu rehber Node.js tabanlı uygulamalarda MuditaKurye üçüncü taraf entegrasyonunu hızlıca başlatmanız için hazırlanmıştır. Aşağıdaki örnekler Express.js kullanan bir REST API servisinin sipariş gönderme ve webhook alma süreçlerini kapsar.

Ön Koşullar

  • Node.js 18+ ve npm (veya pnpm/yarn)
  • MuditaKurye tarafından verilen restaurantId, API Key veya Basic Auth kimlik bilgileri
  • Webhook bildirimlerini alabilecek herkese açık bir URL (geliştirme için ngrok veya Cloudflare Tunnel kullanılabilir)
# Proje klasörü oluşturun
mkdir muditakurye-node && cd muditakurye-node

# Gerekli paketleri yükleyin
npm init -y
npm install express axios dotenv

Ortak Yapılandırma

.env dosyasıyla kimlik bilgilerini yönetin.

MUDITAKURYE_BASE_URL=https://api.muditakurye.com.tr
MUDITAKURYE_API_KEY=yk_sizin_anahtariniz
MUDITAKURYE_RESTAURANT_ID=rest_xxxxx
MUDITAKURYE_STATUS_WEBHOOK_SECRET=whsec_xxxxx

config.js dosyasında yapılandırmayı merkezileştirin.

import 'dotenv/config';

export const config = {
  baseUrl: process.env.MUDITAKURYE_BASE_URL ?? 'https://api.muditakurye.com.tr',
  apiKey: process.env.MUDITAKURYE_API_KEY ?? '',
  restaurantId: process.env.MUDITAKURYE_RESTAURANT_ID ?? '',
  webhookSecret: process.env.MUDITAKURYE_STATUS_WEBHOOK_SECRET ?? '',
};

Sipariş Gönderme

scripts/create-order.js dosyası sipariş oluşturma isteğini gönderir.

import axios from 'axios';
import { randomUUID } from 'crypto';
import { config } from '../config.js';

const client = axios.create({
  baseURL: config.baseUrl,
  headers: {
    'X-API-Key': config.apiKey,
    'Content-Type': 'application/json',
  },
  timeout: 5000,
});

export async function createOrder() {
  const orderId = `ext_${randomUUID()}`;

  const payload = {
    orderId,
    restaurantId: config.restaurantId,
    customerName: 'Ahmet Yılmaz',
    customerPhone: '+905551234567',
    deliveryAddress: 'Atatürk Caddesi No: 123, Çankaya, Ankara',
    paymentMethod: 'CASH',
    paymentCaptured: false,
    total: 149.5,
    currency: 'TRY',
    items: [
      {
        productCode: 'PIZZA_LG',
        productName: 'Büyük Margarita Pizza',
        quantity: 1,
        unitPrice: 129.5,
        totalAmount: 129.5,
        productNote: 'Ekstra peynir olsun',
      },
      {
        productCode: 'DRINK_COLA',
        productName: 'Coca Cola 1L',
        quantity: 1,
        unitPrice: 20,
        totalAmount: 20,
      },
    ],
    notes: 'Kapıyı çalmadan önce arayın',
  };

  const { data } = await client.post('/webhook/third-party/order', payload);
  console.log('Sipariş oluşturma yanıtı:', data);

  return data;
}

if (process.argv[1] === import.meta.url.replace('file://', '')) {
  createOrder().catch((error) => {
    if (error.response) {
      console.error('[MuditaKurye] Hata', error.response.status, error.response.data);
    } else {
      console.error('[MuditaKurye] Ağ hatası', error.message);
    }
    process.exitCode = 1;
  });
}

Webhook Sunucusu

server.js dosyası Express tabanlı bir webhook alıcısıdır. İsteğe bağlı olarak X-MuditaKurye-Signature başlığını doğrular.

import crypto from 'crypto';
import express from 'express';
import { config } from './config.js';

const app = express();
app.use(express.json({ verify: rawBodyBuffer }));

function rawBodyBuffer(req, _res, buf) {
  req.rawBody = buf;
}

function verifySignature(req) {
  if (!config.webhookSecret) {
    return true;
  }
  const signature = req.get('X-MuditaKurye-Signature');
  if (!signature) {
    return false;
  }
  const hmac = crypto.createHmac('sha256', config.webhookSecret);
  hmac.update(req.rawBody);
  const expected = hmac.digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

app.post('/webhook/muditakurye/status', (req, res) => {
  if (!verifySignature(req)) {
    console.warn('[Webhook] İmza doğrulaması başarısız');
    return res.status(401).json({ error: 'invalid signature' });
  }

  const { event, orderId, status, timestamp, reason } = req.body;
  console.log(`[Webhook] ${event} orderId=${orderId} status=${status} time=${timestamp}`);
  if (reason) {
    console.log(`[Webhook] İptal nedeni: ${reason}`);
  }

  // Burada kendi iş mantığınızı çalıştırın (örn. veritabanı güncelleme, bildirim gönderme)

  return res.status(200).json({ received: true });
});

const port = process.env.PORT ?? 3000;
app.listen(port, () => {
  console.log(`[Webhook] Sunucu port ${port} üzerinde çalışıyor`);
});

Test Senaryoları

# Webhook sunucusunu başlatın
node server.js

# Ayrı bir terminalde sipariş oluşturun
node scripts/create-order.js

Webhook sunucusu, MuditaKurye tarafından gönderilen durum bildirimlerini terminale yazar. Geliştirme ortamında dışa açmak için:

ngrok http 3000

Elde edilen URL'yi MuditaKurye restoran ayarlarında Durum Webhook URL alanına girin.

Hata Yönetimi ve Retry

  • axios istemcisine timeout vererek ağ sorunlarında hızlıca yanıt alın.
  • 5xx hatalarında retry mekanizması eklemek için axios-retry kullanılabilir.
  • Webhook yanıtlarınızı 200-299 aralığında tutun. Kendi sisteminizde hata oluşursa 500 dönmek yerine isteği kuyruğa alıp 200 dönmek önerilir.

Kullanışlı Araçlar

  • Joi veya Zod ile gelen/giden payload doğrulaması
  • Winston ile yapılandırılmış loglama
  • BullMQ ile webhook işleme kuyruğu

Sonraki Adımlar

  • examples/python.md ve examples/curl.md sayfalarındaki örneklerle çapraz testler yapın.
  • integration-flow.md dokümanındaki süreç diagramını takımınıza anlatın.
  • best-practices.md rehberindeki güvenlik ve ölçekleme önerilerini uygulayın.