Her pazaryeri sipariş durumunu farklı adlandırıyor. Biri Created diyor, biri awaiting, biri sayı gönderiyor.
Bu adları kodun içine dağıtırsanız üçüncü entegrasyonda yirmi dosyaya dokunmak zorunda kalırsınız.
Kötü hâli
if ($order->marketplace === 'A' && $order->status === 'Created') {
// ...
}
if ($order->marketplace === 'B' && $order->status === 'awaiting_approval') {
// ...
}
Bu kod bir yerde durmuyor. Sipariş listesinde, kargo servisinde, faturada, raporda tekrar ediyor. Dördüncü pazaryeri geldiğinde hepsini bulmanız gerekiyor.
Bulamadığınız yer sessizce yanlış çalışıyor. Hata vermiyor, sadece sipariş yanlış listede duruyor.
Kendi durumunuzu tanımlayın
Önce kendi sisteminizin durumlarını yazın. Pazaryerine bakmadan, kendi iş akışınıza göre:
enum OrderStatus: string
{
case Pending = 'pending'; // onay bekliyor
case Approved = 'approved'; // onaylandı, hazırlanacak
case Preparing = 'preparing'; // hazırlanıyor
case Shipped = 'shipped'; // kargoya verildi
case Delivered = 'delivered'; // teslim edildi
case Cancelled = 'cancelled';
case Returned = 'returned';
}
Bu liste kısa olmalı. Yedi durum yeterli. Pazaryerinin on dört durumunu birebir taşımaya çalışmayın; onların yarısı size aynı şeyi ifade ediyor.
Eşlemeyi bir dosyaya koyun
class TrendyolStatusMapper implements StatusMapper
{
private const MAP = [
'Created' => OrderStatus::Pending,
'Picking' => OrderStatus::Preparing,
'Invoiced' => OrderStatus::Preparing,
'Shipped' => OrderStatus::Shipped,
'Delivered' => OrderStatus::Delivered,
'Cancelled' => OrderStatus::Cancelled,
'Returned' => OrderStatus::Returned,
];
public function toInternal(string $external): OrderStatus
{
return self::MAP[$external]
?? throw new UnknownStatusException($external);
}
}
Artık uygulamanın geri kalanı sadece OrderStatus biliyor. Pazaryeri adı hiçbir yerde geçmiyor.
Bilinmeyen durumda patlayın
Yukarıdaki ?? operatöründen sonra throw var. Bu bilinçli.
Varsayılan bir değere düşerseniz pazaryeri yeni bir durum eklediğinde bunu hiç öğrenmezsiniz. Siparişler sessizce yanlış durumda birikir.
Patlarsa iş failed_jobs tablosuna düşer, siz de tam olarak hangi yeni durumun geldiğini görürsünüz. Bunu bir hata olarak değil, bildirim olarak düşünün.
Ham değeri de saklayın
Eşlenmiş durumu kolona yazın, ham değeri de ayrı bir kolonda tutun:
$order->status = $mapper->toInternal($raw);
$order->external_status = $raw;
Destek ekibi “pazaryeri panelinde şu yazıyor ama sizde bu yazıyor” dediğinde tek bakılacak yer burasıdır. Eşleme hatası mı, gecikme mi, iki saniyede anlaşılır.
Geçiş kurallarını da tek yerde tutun
Eşleme kadar önemli olan ikinci şey, hangi durumdan hangisine geçilebileceği.
Teslim edilmiş bir sipariş tekrar hazırlanıyor durumuna dönmemeli. Pazaryerinden böyle bir olay gelirse bu ya bir gecikme ya da sizin tarafınızda bir hata. Sessizce yazmak yerine reddedin ve loglayın.
private const ALLOWED = [
'pending' => ['approved', 'cancelled'],
'approved' => ['preparing', 'cancelled'],
'preparing' => ['shipped', 'cancelled'],
'shipped' => ['delivered', 'returned'],
'delivered' => ['returned'],
];
Bu tablo olmadan sıra dışı gelen webhook’lar siparişi geri sarabiliyor. Kuyruk sırayı garanti etmediği için bu nadir değil, düzenli olarak oluyor.
Ters yön
Durum güncellemesini pazaryerine siz gönderiyorsanız ters eşleme de lazım. Ama birebir ters çevirmeyin.
Yukarıdaki tabloda Picking ve Invoiced aynı iç duruma gidiyor. Geri dönerken Preparing hangisine gidecek? Kararı açıkça yazın, otomatik türetmeye çalışmayın.
Özet
Kendi durumlarını tanımla. Her pazaryeri için bir eşleyici sınıf. Bilinmeyen değerde patla. Ham değeri sakla.
Dördüncü entegrasyonu eklerken tek bir dosya yazacaksınız. Kural buysa eklemek bir günlük iş, değilse bir haftalık.