Konuyu Oyla:
  • Derecelendirme: 5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Delphi Trendyol Yemek Entegrasyonu
#1
Merhaba, kişisel hobi amaçlı bir projemde kullandığım trendyol yemek entegrasyonu kütüphanemi sizler ile paylaşmak istedim. İhtiyaç duyan arkadaşlar kullanabilirler. Json parse işlemlerinde 3.parti bileşeni olarak açık kaynak olan superobject'den faydalandım. Github da bulunmaktadır. 10.4 ile yazılmıştır. Http bileşeni olarak modern RestRequest bileşenleri kullanılmıştır. SSL dll gerektirmez.

Örnek Kullanım :
var
 TestTrendyolYemek : TTrendyolYemek;
  xTestStr : String;
begin
 TestTrendyolYemek := TTrendyolYemek.Create(nil);
 try
   TestTrendyolYemek.SaticiId := '';
   TestTrendyolYemek.ApiKey := '';
   TestTrendyolYemek.ApiSecretKey := '';
   TestTrendyolYemek.TestMode := True;

   xTestStr := TestTrendyolYemek.TestEt;
   if xTestStr = 'OK' then
     ShowMessage('Test başarılı.')
   else
     ShowMessage('Test başarısız.' + sLineBreak + xTestStr);
 finally
   FreeAndNil(TestTrendyolYemek);
 end;
end;

Kütüphane

unit uTrendyolYemekLib;

{-----------------------------------------------------------------------------
 Yola çıktı ve teslim edildi sadece restoran kuryesi ise gönderilmelidir.
 Ödeme tipi yok hepsi online
-----------------------------------------------------------------------------}

interface

 uses SysUtils, Classes, REST.Types, REST.Client, Data.Bind.Components, Data.Bind.ObjectScope, Soap.XSBuiltIns, REST.Authenticator.Basic;
 
 type TTrendyolLogProc = procedure (const FormHandle:Cardinal;ADir,AStr:String;AMemoAdd:Boolean);

 // Yeni, Onaylandı, Hazırlandı, Teslim edildi, Restoran iptal, Müşteri iptal, İşlem hatası
 type TTrendyolOrderStatus = (StsCreated,StsPicking,StsInvoiced,StsDelivered,StsUnSupplied,StsCancelled,StsError);

 // Normal onay, Hazırlandı, Sadece restoran kuryeleri Yola çıktı, Sadece restoran kuryeleri Normal teslim, Restoran iptal
 type TTrendyolNextStatus=(NxtVerify,NxtPrepare,NxtShipped,NxtDeliver,NxtRestCancel);

 type
   TTrendyolRestaurantInfo = record
   id : String; // Restoran id
   status : Boolean; // Restoran açık mı
   name : String; // Restoran adı
   email : String; // Restoran mail
   run : Boolean; // Çalıştı mı
 end;

 type
   TTrendyolRestaurantList = record
   id : String; // Restoran id
   status : Boolean; // Restoran açık mı
   name : String; // Restoran adı
   email : String; // Restoran mail    
 end;
 type TTrendyolRestaurantListArray = Array of TTrendyolRestaurantList;

 type
   TTrendyolOrderCancel = record
   id : String; // iptal id
   cancelMessage : String; // iptal mesaj
 end;
 type TTrendyolOrderCancels = Array of TTrendyolOrderCancel;

 type
   TTrendyolPaymentList = record
   name : String; // ödeme adı
   paymenttype : Integer; // ödeme id
 end;
 type TTrendyolPaymentLists = Array of TTrendyolPaymentList;

 type
   TOrderProductDisplayOption = record
   optionNameDisplay : String; // Ürün opsiyon açıklaması
   options : Array of TOrderProductDisplayOption;
 end;
 type TOrderProductDisplayOptions = Array of TOrderProductDisplayOption;

 type
   TOrderProductDisplay = record
   productId : String; // Ürün id
   count : Double; // Miktar
   price : Double; // Opsiyonsuz fiyat
   optionPrice : Double; // Opsiyonlar fiyat
   priceWithOption : Double; // Opsiyon dahil fiyat
   totalPrice : Double; // Toplam opsiyonsuz fiyat
   totalOptionPrice : Double; // Toplam opsiyonlar fiyat
   totalPriceWithOption : Double; // Toplam opsiyonlar dahil fiyat
   nameDisplay : String; // Ürün adı
   options : TOrderProductDisplayOptions; // Ürün opsiyonlar
 end;
 type TOrderProductsDisplays = Array of TOrderProductDisplay;

 type
   TTrendyolOrder = record
   id : String; // Sipariş id
   orderCode : String; // Sipariş kodu
   storeId : Integer; // Trendyol restoran id
   deliveryType : Integer; // 0 Restoran getirsin 1 Trendyol getirsin
   packageCreationDate : TDateTime; // Sipariş tarihi
   totalPrice : Extended; // Sipariş tutarı
   customerId : String; // Müşteri Id
   customerName : String; // Müşteri adı
   address : String; // adres
   addressDescription : String; // adres açıklaması
   phoneNumber : String; // Telefon
   clientLatitude : Double; // Müşteri adres enlem
   clientLongitude : Double; // Müşteri adres boylam
   paymentMethod : Integer; // Ödeme numarası
   paymentMethodText : String; // Ödeme açıklaması
   customerNote : String; // Müşteri notu
   productsDisplays : TOrderProductsDisplays; // Ürünler
 end;
 type TTrendyolOrders = Array of TTrendyolOrder;

 type
 TTrendyolYemek = class(TComponent)
 private
   FMainurl: String;
   FTestMode: Boolean;
   FSaticiId: String;
   FApiKey: String;
   FApiSecretKey: String;
   FLogFormHandle: Cardinal;
   FLogRestoranAdi: String;
   FLogModule: String;
   FRestaurantId: String;
   FEMail: String;
   procedure setTestMode(const Value: Boolean);
   procedure LogAdd(const AModule,AValue:String);
   function TrendyolRequest(const AUrl,ARequestType,ABody:String;AHeaderName,AHeaderValue:Array of String):String;
   function UserInfoNull:Boolean;
   function RestaurantInfoNull:Boolean;
   function TrendyolUnixDateTimeToDateTime(const AUnixTime:Int64):TDateTime;
   function TrendyolDateTimeToUnixDateTime(const ADateTime:TDateTime):Int64;
 public
   FLogProc:TTrendyolLogProc;
   constructor Create(AOwner: TComponent); override;
   function TestEt:String;
   function GetRestaurantList:TTrendyolRestaurantListArray;
   function GetRestaurantStatus: TTrendyolRestaurantInfo;
   function SetRestaurantStatus(const AEnable:Boolean):Boolean;
   function GetOrderCancelList:TTrendyolOrderCancels;
   function GetOrderCancelItemList(const AOrderId:String):String;
   function GetOrders(const ANewOrder:Boolean;var AJsonStr:String):TTrendyolOrders;
   function GetOrderStatus(const AOrderId:String):TTrendyolOrderStatus;
   function SetOrderStatus(const AOrderId:String;const AType:TTrendyolNextStatus;const ACancelId:String):Boolean;
   function GetPaymentList:TTrendyolPaymentLists;
 published
   property TestMode:Boolean read FTestMode write setTestMode;
   property SaticiId:String read FSaticiId write FSaticiId;
   property ApiKey:String read FApiKey write FApiKey;
   property ApiSecretKey:String read FApiSecretKey write FApiSecretKey;

   property RestaurantId:String read FRestaurantId write FRestaurantId;
   property EMail:String read FEMail write FEMail;
   
   property LogFormHandle:Cardinal read FLogFormHandle write FLogFormHandle;
   property LogModule:String read FLogModule write FLogModule;
   property LogRestoranAdi:String read FLogRestoranAdi write FLogRestoranAdi;
 end;

implementation
 uses DateUtils, StrUtils, superobject;

{ TTrendyolYemek }

constructor TTrendyolYemek.Create(AOwner: TComponent);
begin
 inherited Create(AOwner);
 TestMode := False;
 FLogFormHandle := 0;
end;

function TTrendyolYemek.GetOrderCancelItemList(const AOrderId: String): String;
var
 Ind,Ind2 : Integer;
 xSO : ISuperObject;
 xSAProducts,xArrItems : TSuperArray;
 xGetJson : String;
 xUrl,xBody : String;
begin
 Result := '';
 try
   if UserInfoNull then
     Exit;
   if RestaurantInfoNull then
     Exit;

   xUrl := '/suppliers/' + SaticiId + '/packages/' + AOrderId + '?storeId=' + RestaurantId;
   xBody := '';

   xGetJson := TrendyolRequest(xUrl,'GET',xBody,['x-agentname','x-executor-user'],['uygulamaadi',EMail]);
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
     begin
       xSAProducts := xSO.A['lines'];
       if xSAProducts <> nil then
       begin
         for Ind := 0 to Pred(xSAProducts.Length) do
         begin
           xArrItems := xSAProducts[Ind].A['items'];
           if xArrItems <> nil then
           begin
             for Ind2 := 0 to Pred(xArrItems.Length) do
             begin
               if Result = '' then
                 Result := '"' + xArrItems[Ind2].S['packageItemId'] + '"'
               else
                 Result := Result + ',"' + xArrItems[Ind2].S['packageItemId'] + '"';
             end;
           end;
         end;
       end;
     end
     else
       LogAdd('TrendyolApiError',Format('Process:GetOrderCancelItemList JsonParseError:%s',[xGetJson]));
   end
   else
     LogAdd('TrendyolApiError',Format('Process:GetOrderCancelItemList Json:%s',[xGetJson]));
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:GetOrderCancelItemList Message:%s Json:%s',[e.Message,xGetJson]));
   end;
 end;
end;

function TTrendyolYemek.GetOrderCancelList: TTrendyolOrderCancels;
begin
 SetLength(Result,4);
 
 Result[0].id := '621';
 Result[0].cancelMessage := 'Tedarik problemi';

 Result[1].id := '622';
 Result[1].cancelMessage := 'Mağaza kapalı';  

 Result[2].id := '623';
 Result[2].cancelMessage := 'Mağaza siparişi hazırlayamıyor';

 Result[3].id := '623';
 Result[3].cancelMessage := 'Yüksek yoğunluk / Kurye yok';
end;

function TTrendyolYemek.GetOrders(const ANewOrder: Boolean; var AJsonStr: String): TTrendyolOrders;
var
 Ind, Ind2,Ind3,Ind4 : Integer;
 xSO,xSOArrObj : ISuperObject;
 xSA,xSAProducts : TSuperArray;
 xArrModifier,xArrExtra,xArrRemove : TSuperArray;
 xArrModifier2,xArrExtra2,xArrRemove2 : TSuperArray;
 xGetJson : String;
 xUrl,xBody : String;
 xHigh,xHigh2 : Integer;
begin
 SetLength(Result,0);
 try
   if UserInfoNull then
     Exit;
   if RestaurantInfoNull then
     Exit;

   if ANewOrder then
   begin
     xUrl := '/suppliers/' + SaticiId + '/packages';
     xUrl := xUrl + '?storeId=' + RestaurantId + '&packageStatuses=Created';
     xBody := '';
   end
   else
   begin
     // Son 1 saat iptaller
     xUrl := '/suppliers/' + SaticiId + '/packages';
     xUrl := xUrl + '?storeId=' + RestaurantId + '&packageStatuses=Returned&packageStatuses=Cancelled';
     xUrl := xUrl + '&packageModificationStartDate=' + IntToStr(TrendyolDateTimeToUnixDateTime(IncHour(Now,-1)));
     xUrl := xUrl + '&packageModificationEndDate=' + IntToStr(TrendyolDateTimeToUnixDateTime(Now));
     xBody := '';
   end;

   xGetJson := TrendyolRequest(xUrl,'GET',xBody,['x-agentname','x-executor-user'],['uygulamaadi',EMail]);
   AJsonStr := xGetJson;
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
     begin
       xSA := xSO.A['content'];
       if xSA <> nil then
       begin
         SetLength(Result,xSA.Length);
         for Ind := 0 to Pred(xSA.Length) do
         begin
           with Result[Ind] do
           begin
             xSOArrObj := xSA.O[Ind];

             {$REGION 'Üst Bilgi'}
               id := xSOArrObj.S['id'];
               orderCode := xSOArrObj.S['orderCode'];
               storeId := xSOArrObj.I['storeId'];

               if xSOArrObj.S['deliveryType'] = 'STORE' then
                 deliveryType := 0
               else
                 deliveryType := 1;

               totalPrice := xSOArrObj.D['totalPrice'];

               if xSOArrObj.O['customer'] <> nil then
               begin
                 customerId := xSOArrObj.O['customer'].S['id'];
                 customerName := Trim(xSOArrObj.O['customer'].S['firstName'] + ' ' + xSOArrObj.O['customer'].S['lastName']);
               end
               else
               begin
                 customerId := '';
                 customerName := '';
               end;

               if xSOArrObj.O['address'] <> nil then
               begin
                 if xSOArrObj.O['address'].S['neighborhood'] <> '' then
                   address := 'Semt:' + xSOArrObj.O['address'].S['neighborhood'];
                 address := address + ' ' + xSOArrObj.O['address'].S['address1'];
                 if xSOArrObj.O['address'].S['apartmentNumber'] <> '' then
                   address := address + ' Apt:' + xSOArrObj.O['address'].S['apartmentNumber'];
                 if xSOArrObj.O['address'].S['floor'] <> '' then
                   address := address + ' Kat:' + xSOArrObj.O['address'].S['floor'];
                 if xSOArrObj.O['address'].S['doorNumber'] <> '' then
                   address := address + ' Kapı:' + xSOArrObj.O['address'].S['doorNumber'];
                 if xSOArrObj.O['address'].S['company'] <> '' then
                   address := address + ' Firma:' + xSOArrObj.O['address'].S['company'];
                 if xSOArrObj.O['address'].S['city'] <> '' then
                 begin
                   address := address + ' ' + xSOArrObj.O['address'].S['city'];
                   if xSOArrObj.O['address'].S['district'] <> '' then
                     address := address + ' / ' + xSOArrObj.O['address'].S['district'];
                 end;

                 addressDescription := xSOArrObj.O['address'].S['addressDescription'];
                 phoneNumber := xSOArrObj.O['address'].S['phone'];
                 clientLatitude := StrToFloatDef(xSOArrObj.O['address'].S['latitude'],0);
                 clientLongitude := StrToFloatDef(xSOArrObj.O['address'].S['longitude'],0);
               end
               else
               begin
                 clientLatitude := 0;
                 clientLongitude := 0;
               end;

               paymentMethod := 1;
               paymentMethodText := 'Online Ödeme';
               customerNote := xSOArrObj.S['customerNote'];
               packageCreationDate := TrendyolUnixDateTimeToDateTime(StrToInt64Def(xSOArrObj.S['packageCreationDate'],0));
             {$ENDREGION}

             {$REGION 'Products'}
               xSAProducts := xSOArrObj.A['lines'];
               if xSAProducts <> nil then
               begin
                 SetLength(Result[Ind].productsDisplays,xSAProducts.Length);
                 for Ind2 := 0 to Pred(xSAProducts.Length) do
                 begin
                   with Result[Ind].productsDisplays[Ind2] do
                   begin
                     productId := xSAProducts[Ind2].S['productId'];
                     count := xSAProducts[Ind2].A['items'].Length;
                     price := xSAProducts[Ind2].D['price'];
                     optionPrice := xSAProducts[Ind2].D['unitSellingPrice'] - xSAProducts[Ind2].D['price'];
                     priceWithOption := xSAProducts[Ind2].D['unitSellingPrice'];
                     totalPrice := price * count;
                     totalOptionPrice := optionPrice * count;
                     totalPriceWithOption := priceWithOption * count;
                     nameDisplay := xSAProducts[Ind2].S['name'];

                     {$REGION 'Extra'}
                       xArrExtra := xSAProducts[Ind2].A['extraIngredients']; // Extralar
                       for Ind3 := 0 to Pred(xArrExtra.Length) do
                       begin
                         SetLength(options,Succ(Length(options)));
                         options[Pred(Length(options))].optionNameDisplay := xArrExtra[Ind3].S['name'];
                       end;
                     {$ENDREGION}

                     {$REGION 'İstemiyorum'}
                       xArrRemove := xSAProducts[Ind2].A['removedIngredients']; // İstemiyorum
                       for Ind3 := 0 to Pred(xArrRemove.Length) do
                       begin
                         SetLength(options,Succ(Length(options)));
                         options[Pred(Length(options))].optionNameDisplay := xArrRemove[Ind3].S['name'] + '(Çıkarılan)';
                       end;
                     {$ENDREGION}

                     {$REGION 'Alt Ürün'}
                       xArrModifier := xSAProducts[Ind2].A['modifierProducts']; // Ürün
                       for Ind3 := 0 to Pred(xArrModifier.Length) do
                       begin
                         SetLength(options,Succ(Length(options)));
                         xHigh := Pred(Length(options));
                         options[xHigh].optionNameDisplay := xArrModifier[Ind3].S['name'];
                         {$REGION 'Alt Ürün Extra'}
                           xArrExtra2 := xArrModifier[Ind3].A['extraIngredients']; // Extralar 2
                           for Ind4 := 0 to Pred(xArrExtra2.Length) do
                           begin
                             SetLength(options[xHigh].options,Succ(Length(options[xHigh].options)));
                             xHigh2 := Pred(Length(options[xHigh].options));
                             options[xHigh].options[xHigh2].optionNameDisplay := xArrExtra2[Ind4].S['name'];
                           end;
                         {$ENDREGION}

                         {$REGION 'Alt Ürün İstemiyorum'}
                           xArrRemove2 := xArrModifier[Ind3].A['removedIngredients']; // İstemiyorum 2
                           for Ind4 := 0 to Pred(xArrRemove2.Length) do
                           begin
                             SetLength(options[xHigh].options,Succ(Length(options[xHigh].options)));
                             xHigh2 := Pred(Length(options[xHigh].options));
                             options[xHigh].options[xHigh2].optionNameDisplay := xArrRemove2[Ind4].S['name'] + '(Çıkarılan)';
                           end;
                         {$ENDREGION}

                         {$REGION 'Alt Ürün Alt Ürün'}
                           xArrModifier2 := xArrModifier[Ind3].A['modifierProducts']; // Ürün 2
                           for Ind4 := 0 to Pred(xArrModifier2.Length) do
                           begin
                             SetLength(options[xHigh].options,Succ(Length(options[xHigh].options)));
                             xHigh2 := Pred(Length(options[xHigh].options));
                             options[xHigh].options[xHigh2].optionNameDisplay := xArrModifier2[Ind4].S['name'];
                           end;
                         {$ENDREGION}
                       end;
                     {$ENDREGION}

                   end;
                 end;
               end;
             {$ENDREGION}

           end;
         end;
       end;
     end
     else
       LogAdd('TrendyolApiError',Format('Process:GetOrders JsonParseError:%s',[xGetJson]));
   end
   else
     LogAdd('TrendyolApiError',Format('Process:GetOrders Json:%s',[xGetJson]));
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:GetOrders Message:%s Json:%s',[e.Message,xGetJson]));
   end;
 end;
end;

function TTrendyolYemek.GetOrderStatus(const AOrderId: String): TTrendyolOrderStatus;
var
 xSO : ISuperObject;
 xGetJson : String;
 xUrl,xBody : String;
begin
 Result := StsError;
 try
   if UserInfoNull then
     Exit;
   if RestaurantInfoNull then
     Exit;

   xUrl := '/suppliers/' + SaticiId + '/packages/' + AOrderId + '?storeId=' + RestaurantId;
   xBody := '';

   xGetJson := TrendyolRequest(xUrl,'GET',xBody,['x-agentname','x-executor-user'],['uygulamaadi',EMail]);
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
     begin
       if xSO.S['packageStatus'] = 'Created' then
         Result := StsCreated
       else if xSO.S['packageStatus'] = 'Picking' then
         Result := StsPicking
       else if xSO.S['packageStatus'] = 'Invoiced' then
         Result := StsInvoiced
       else if xSO.S['packageStatus'] = 'Shipped' then
         Result := StsInvoiced
       else if xSO.S['packageStatus'] = 'Delivered' then
         Result := StsDelivered
       else if xSO.S['packageStatus'] = 'Returned' then
         Result := StsCancelled
       else if xSO.S['packageStatus'] = 'Cancelled' then
         Result := StsCancelled
       else if xSO.S['packageStatus'] = 'UnSupplied' then
         Result := StsUnSupplied;
     end
     else
       LogAdd('TrendyolApiError',Format('Process:GetOrderStatus JsonParseError:%s',[xGetJson]));
   end
   else
     LogAdd('TrendyolApiError',Format('Process:GetOrderStatus Json:%s',[xGetJson]));
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:GetOrderStatus Message:%s Json:%s',[e.Message,xGetJson]));
   end;
 end;
end;

function TTrendyolYemek.GetPaymentList: TTrendyolPaymentLists;
begin
 SetLength(Result,1);
 Result[0].paymenttype := 1;
 Result[0].name := 'Online Ödeme';
end;

function TTrendyolYemek.GetRestaurantList: TTrendyolRestaurantListArray;
var
 Ind : Integer;
 xSO : ISuperObject;
 xSA : TSuperArray;
 xGetJson : String;
begin
 SetLength(Result,0);
 try
   if UserInfoNull then
     Exit;

   xGetJson := TrendyolRequest('/suppliers/' + SaticiId + '/restaurants','GET','',[],[]);
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
     begin
       xSA := xSO.A['restaurants'];
       SetLength(Result,xSA.Length);
       for Ind := 0 to Pred(xSA.Length) do
       begin
         with Result[Ind] do
         begin
           id := xSA[Ind].S['id'];
           name := xSA[Ind].S['name'];
           status := xSA[Ind].S['workingStatus'] = 'OPEN';
           email := xSA[Ind].S['email'];
         end;
       end;
     end
     else
       LogAdd('TrendyolApiError',Format('Process:GetRestaurantList JsonParseError:%s',[xGetJson]));
   end
   else
     LogAdd('TrendyolApiError',Format('Process:GetRestaurantList Json:%s',[xGetJson]));
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:GetRestaurantList Message:%s Json:%s',[e.Message,xGetJson]));
   end;
 end;
end;

function TTrendyolYemek.GetRestaurantStatus: TTrendyolRestaurantInfo;
var
 Ind : Integer;
 xTrendyolRestaurantListArray : TTrendyolRestaurantListArray;
begin
 Result.run := False;
 try
   if UserInfoNull then
     Exit;
   if RestaurantInfoNull then
     Exit;
     
   xTrendyolRestaurantListArray := GetRestaurantList;
   Result.run := True;
   for Ind := Low(xTrendyolRestaurantListArray) to High(xTrendyolRestaurantListArray) do
   begin      
     if RestaurantId = xTrendyolRestaurantListArray[Ind].id then
     begin  
       Result.id := xTrendyolRestaurantListArray[Ind].id;
       Result.name := xTrendyolRestaurantListArray[Ind].name;
       Result.status := xTrendyolRestaurantListArray[Ind].status;
       Result.email := xTrendyolRestaurantListArray[Ind].email;
       Break;
     end;
   end;
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:GetRestaurantStatus Message:%s',[e.Message]));
   end;
 end;  
end;

procedure TTrendyolYemek.LogAdd(const AModule, AValue: String);
begin
 if (FLogFormHandle > 0) and Assigned(FLogProc) then
 begin
   FLogProc(FLogFormHandle,FLogModule + '\' + AModule,FLogRestoranAdi + ' ' + AValue,True);
 end;
end;

function TTrendyolYemek.RestaurantInfoNull: Boolean;
begin
 Result := RestaurantId.Trim.Equals('') or EMail.Trim.Equals('');
end;

function TTrendyolYemek.SetOrderStatus(const AOrderId: String; const AType: TTrendyolNextStatus; const ACancelId: String): Boolean;
var
 xSO : ISuperObject;
 xGetJson : String;
 xBody : String;
 xUrl : String;
begin
 Result := False;
 try
   if UserInfoNull then
     Exit;  
           
   xBody := '';
   case AType of
     NxtVerify:
       begin
         xUrl := '/suppliers/' + SaticiId + '/packages/picked';
         xBody := '{"packageId":"' + AOrderId + '","preparationTime":30}';
       end;
     NxtPrepare:
       begin
         xUrl := '/suppliers/' + SaticiId + '/packages/invoiced';
         xBody := '{"packageId":"' + AOrderId + '"}';
       end;
     NxtShipped:
       begin
         xUrl := '/suppliers/' + SaticiId + '/packages/' + AOrderId + '/manual-shipped';
         xBody := '{}';
       end;
     NxtDeliver:
       begin
         xUrl := '/suppliers/' + SaticiId + '/packages/' + AOrderId + '/manual-delivered';
         xBody := '{}';
       end;
     NxtRestCancel:
       begin
         xUrl := '/suppliers/' + SaticiId + '/packages/unsupplied';
         xBody := '{"packageId":"' + AOrderId + '","itemIdList":[' + GetOrderCancelItemList(AOrderId) + '],"reasonId":' + ACancelId + '}'
       end;
   end;

   xGetJson := TrendyolRequest(xUrl,'PUT',xBody,['x-agentname','x-executor-user'],['uygulamaadi',EMail]);
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
     begin
       Result := xGetJson.Trim = '';
     end
     else
       LogAdd('TrendyolApiError',Format('Process:SetOrderStatus JsonParseError:%s',[xGetJson]));
   end
   else
     LogAdd('TrendyolApiError',Format('Process:SetOrderStatus Json:%s',[xGetJson]));
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:SetOrderStatus Message:%s Json:%s',[e.Message,xGetJson]));
   end;
 end;
end;

function TTrendyolYemek.SetRestaurantStatus(const AEnable: Boolean): Boolean;
var
 xSO : ISuperObject;
 xGetJson : String;
 xBody : String;
begin
 Result := False;
 try
   if UserInfoNull then
     Exit;
   if RestaurantInfoNull then
     Exit;      
           
   xBody := '';
   if AEnable then
     xBody := '{"status":"OPEN"}'
   else
     xBody := '{"status":"CLOSED"}';

   xGetJson := TrendyolRequest('/suppliers/' + SaticiId + '/restaurants/' + RestaurantId + '/status','PUT',xBody,[],[]);
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
     begin
       Result := xGetJson.Trim = '';
     end
     else
       LogAdd('TrendyolApiError',Format('Process:SetRestaurantStatus JsonParseError:%s',[xGetJson]));
   end
   else
     LogAdd('TrendyolApiError',Format('Process:SetRestaurantStatus Json:%s',[xGetJson]));
 except
   on e:Exception do
   begin
     LogAdd('TrendyolApiError',Format('Process:SetRestaurantStatus Message:%s Json:%s',[e.Message,xGetJson]));
   end;
 end;
end;

procedure TTrendyolYemek.setTestMode(const Value: Boolean);
begin
 FTestMode := Value;
 if FTestMode then
   FMainurl := 'https://stageapi.trendyol.com/mealgw'
 else
   FMainurl := 'https://api.trendyol.com/mealgw';
end;

function TTrendyolYemek.TestEt: String;
var
 xSO : ISuperObject;
 xGetJson : String;
begin
 try
   xGetJson := TrendyolRequest('/suppliers/' + SaticiId + '/restaurants','GET','',[],[]);
   if Copy(xGetJson,1,2) = 'OK' then
   begin
     xGetJson := Copy(xGetJson,4,MaxInt);
     xSO := SO(xGetJson);
     if xSO <> nil then
       Result := 'OK'
     else
       Result :=  Format('Process:GetRestaurantList JsonParseError:%s',[xGetJson]);
   end
   else
     Result := Format('Process:GetRestaurantList Json:%s',[xGetJson]);
 except
   on e:Exception do
   begin
     Result := Format('Process:GetRestaurantList Message:%s Json:%s',[e.Message,xGetJson]);
   end;
 end;
end;

function TTrendyolYemek.TrendyolRequest(const AUrl, ARequestType, ABody: String; AHeaderName, AHeaderValue: array of String): String;
var
 Ind : Integer;
 xRESTClient: TRESTClient;
 xRESTRequest: TRESTRequest;
 xRESTResponse: TRESTResponse;
 xBasicAuthenticator : THTTPBasicAuthenticator;
begin
 Result := '';
 try
   xRESTClient := TRESTClient.Create(nil);
   xRESTResponse := TRESTResponse.Create(nil);
   xRESTRequest := TRESTRequest.Create(nil);
   xBasicAuthenticator := THTTPBasicAuthenticator.Create(ApiKey,ApiSecretKey);
   try
     with xRESTClient do
     begin
       BaseURL := FMainurl + AUrl;
       ConnectTimeout := 10000;
       ReadTimeout := 30000;
       Authenticator := xBasicAuthenticator;
     end;
     with xRESTRequest do
     begin
       AssignedValues := [TAssignedValue.rvConnectTimeout, TAssignedValue.rvReadTimeout];
       Client := xRESTClient;
       Response := xRESTResponse;
       ConnectTimeout := 10000;
       ReadTimeout := 30000;
       if ARequestType = 'POST' then
       begin
         Method := rmPOST;
         if ABody.Trim <> '' then
           Params.AddItem('BodyPost',ABody, TRESTRequestParameterKind.pkREQUESTBODY, [], TRESTContentType.ctAPPLICATION_JSON);
       end
       else if ARequestType = 'PUT' then
       begin
         Method := rmPUT;
         if ABody.Trim <> '' then
           Params.AddItem('BodyPost',ABody, TRESTRequestParameterKind.pkREQUESTBODY, [], TRESTContentType.ctAPPLICATION_JSON);
       end
       else if ARequestType = 'GET' then
         Method := rmGET;

       for Ind := Low(AHeaderName) to High(AHeaderName) do
         Params.AddHeader(AHeaderName[Ind],AHeaderValue[Ind]);
     end;
     xRESTRequest.Execute;
     if xRESTResponse.StatusCode = 200 then
       Result := 'OK=' + xRESTResponse.Content
     else
       Result := 'ERROR=' + Format('Process:TrendyolRequest Url:%s, Method:%s, Status:%d, Content:%s',[AUrl,ARequestType,xRESTResponse.StatusCode,xRESTResponse.Content]);
   finally
     FreeAndNil(xBasicAuthenticator);
     FreeAndNil(xRESTRequest);
     FreeAndNil(xRESTResponse);
     FreeAndNil(xRESTClient);
   end;
 except
   on e:Exception do
   begin
     Result := 'ERROR=' + Format('Process:TrendyolRequest Url:%s, Method:%s, Message:%s',[AUrl,ARequestType,e.Message]);
   end;
 end;
end;

function TTrendyolYemek.TrendyolUnixDateTimeToDateTime(const AUnixTime: Int64): TDateTime;
var
 xNotMillisecond : Integer;
begin
 try
   xNotMillisecond := Round(AUnixTime/1000); // Milisaniye temizlenir
   Result := UnixToDateTime(xNotMillisecond);
   Result := TTimeZone.Local.ToLocalTime(Result); // Unix to GMT+3
 except
   Result := 0;
 end;
end;

function TTrendyolYemek.TrendyolDateTimeToUnixDateTime(const ADateTime: TDateTime): Int64;
var
 xUnixDateTime : TDateTime;
begin
 try
   xUnixDateTime := TTimeZone.Local.ToUniversalTime(ADateTime); // GMT+3 to Unix
   Result := DateTimeToUnix(xUnixDateTime) * 1000;
 except
   Result := 0;
 end;
end;

function TTrendyolYemek.UserInfoNull: Boolean;
begin
 Result := ApiKey.Trim.Equals('') or ApiSecretKey.Trim.Equals('') or SaticiId.Trim.Equals('');
end;

end.
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#2
Eline emeğine sağlık paylaşımın için teşekkürler @narkotik
Kalan ömrünün en genç build’indesin.
Counter artar, deadline sabit.
Age++ çalışıyor, rollback yok.
Her yer exception
Cevapla
#3
Emeğinize sağlık, arasan bulamazsın nitelikte bi konu Smile
There is no place like "127.0.0.1"

"Vatanını en çok seven, görevini en iyi yapandır."

Cevapla
#4
Rica ederim, ben ihtiyacım olan endpointleri aldım. Lazım oldukça geliştirilebilir
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#5
teşekkürler , elinize sağlık güzel bir paylaşım olmuş.
Cevapla
#6
Gerçekten mükemmel bir paylaşım. Üstelik komponent haline getirip paylaşmışsın ve yapı olarak çok beğendim. Eline, emeğine sağlık kardeşim. Böyle bir paylaşımı ücretli bile vermezler. Çok teşekkür ederim. Bu arada entegrasyonla ilgili bir sorum olacak.

1) Ben mesela Getiryemek ile entegrasyon yaptım. Onlar da basic authentication kullandırıyor ama login olduğunda sana 1 saat geçerli bir token gönderiyor. Trendyol da durum nasıl acaba? Ben kodlarını incelediğimde Auth ile ilgili bir kısım göremedim o yüzden sorayım dedim. Trandyol Api yi de incelediğimde test ortamı dışında başka bir bilgi bulamadım. Basic authentication da username ve password bilgileri body olarak gönderiliyor diye biliyorum ama Trendyol da APIKEY ve APISECRETKEY parametreleri var. Bunlarla mı login oluyoruz yoksa username ve password gönderince bunlar bize mi geliyor (RestoranId ile birlikte) ?

2) Prepare ve Shippping endpointlerini ard arda kullanabiliyor muyuz? Yani daha doğrusu Getir de olduğu gibi servislerinde rate-limiter filan kullanıyorlar mı?

Bu konuda yardımcı olursan çok sevinirim.
Teşekkürler şimdiden.
Ne ekersen onu biçersin!  Idea
Cevapla
#7
(18-10-2022, Saat: 13:30)tmrksmt Adlı Kullanıcıdan Alıntı: Gerçekten mükemmel bir paylaşım. Üstelik komponent haline getirip paylaşmışsın ve yapı olarak çok beğendim. Eline, emeğine sağlık kardeşim. Böyle bir paylaşımı ücretli bile vermezler. Çok teşekkür ederim. Bu arada entegrasyonla ilgili bir sorum olacak.

1) Ben mesela Getiryemek ile entegrasyon yaptım. Onlar da basic authentication kullandırıyor ama login olduğunda sana 1 saat geçerli bir token gönderiyor. Trendyol da durum nasıl acaba? Ben kodlarını incelediğimde Auth ile ilgili bir kısım göremedim o yüzden sorayım dedim. Trandyol Api yi de incelediğimde test ortamı dışında başka bir bilgi bulamadım. Basic authentication da username ve password bilgileri body olarak gönderiliyor diye biliyorum ama Trendyol da APIKEY ve APISECRETKEY parametreleri var. Bunlarla mı login oluyoruz yoksa username ve password gönderince bunlar bize mi geliyor (RestoranId ile birlikte) ?

2) Prepare ve Shippping endpointlerini ard arda kullanabiliyor muyuz? Yani daha doğrusu Getir de olduğu gibi servislerinde rate-limiter filan kullanıyorlar mı?

Bu konuda yardımcı olursan çok sevinirim.
Teşekkürler şimdiden.

Rica ederim.
1-) Kodlar içerisinde bütün isteklerde kullanılan TrendyolRequest fonksiyonu içerisinde THTTPBasicAuthenticator.Create(ApiKey,ApiSecretKey); ile basic auth yapılıyor. Componente doldurduğunuz apikey ve apisecretkey bilgilerini otomatik ekliyor isteklerde.
2-) Getir yemekde durum geçişleri arasında 1 dakika beklemek zorunluluğu var, Trendyolda yok. Diğer endpointlerde de Rate limit görmedim.
3-) Bu arada bir süre önce trendyol yemekde gelen bir güncelleme ile yukarıdaki kodlarda durum güncellemede ufak bir değişiklik oldu düzelttim.
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#8
Cevabın için tekrardan çok teşekkür ediyorum.

Peki isteklerde gerekli olan "RestaurantId" nereden dönüyor acaba?

Bu arada yukarıdaki kodlar son güncellemeli haliyle mi?
Ne ekersen onu biçersin!  Idea
Cevapla
#9
(18-10-2022, Saat: 14:30)tmrksmt Adlı Kullanıcıdan Alıntı: Cevabın için tekrardan çok teşekkür ediyorum.

Peki isteklerde gerekli olan "RestaurantId" nereden dönüyor acaba?

Bu arada yukarıdaki kodlar son güncellemeli haliyle mi?

Kodlar güncel, GetRestaurantList fonksiyonu ile restoran listenizi alıyorsunuz. Hangi restoranı kullanıyorsanız onun id değerini componentte dolduruyorsunuz. 
Yalnızım ama bir kente yürüyen ordu gibiyim, edebiyattan kaçınmalıyım..
Cevapla
#10
Çok teşekkürler... Herşey gönlünce olsun inşallah.https://www.delphican.com/newreply.php?tid=6678

Bu arada inşallah çok büyük bir güncelleme olmamıştır diye umuyorum Smile) Şimdi tek tek kodları karşılaştırmam gerekecek hangi kısımlarda değişiklik olup olmadığını bilmiyorum çünkü. API lerine baktığmda şu Id alanı 64 bitlik değer dönecek filan diyorlardı acaba onun dışında farklı bişey oldu mu bilemiyorum tabi.
Ne ekersen onu biçersin!  Idea
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  yapay zeka delphi kl007 9 627 26-02-2026, Saat: 09:12
Son Yorum: mrmarman
  Win 11 ve Delphi 7 Minimize sorunu. enigma 7 498 11-02-2026, Saat: 10:27
Son Yorum: RAD Coder
Question Delphi formunu nasıl otomatik tam ekran yapabilirim ? erdemklt0 2 324 23-01-2026, Saat: 10:02
Son Yorum: csunguray
  PAVO Pos Cihaz Entegrasyonu (Yeni Nesil ÖKC) RAD Coder 3 1.093 26-12-2025, Saat: 17:06
Son Yorum: rmzgenius
  Delphi SLL kullanım sorunu Bay_Y 12 1.317 22-12-2025, Saat: 18:11
Son Yorum: Bay_Y



Konuyu Okuyanlar: 2 Ziyaretçi