API z firmy kurierskiej metodą POST

0

Witam. Jestem w trakcie tworzenia oprogramowania do generowania przesyłek do brokera/kuriera poprzez API brokera.
Mam problem z jednym parametrem w której zmienną jest tablica struktur.
Wykorzystuję Tidhttp do wysyłania POST

W dokumentacji API widnieje:

Parametry wejściowe funkcji CheckPrices.xml:
session string(32)
paymentType string(20)
receiverPostCode string(10)
packages tablica struktur package1

Parametry package1
weight float
height float
width float
length float

W przypadku parametrów typu String nie mam problemu, lecz niewiem jak ugryźć tą tablicę struktur.

procedure Zamow_paczke(order:IXMLDocument; response : TStream);
var
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  Node: IXMLNode;
  package: TStringList;
begin
  Node:=order.DocumentElement;
  lParamList := TStringList.Create;
  package := TStringList.Create;
  lParamList.Add('session='+session);
  lParamList.Add('paymentType='+Node.ChildNodes['paymentType'].Text);
  lParamList.Add('receiverPostCode='+Node.ChildNodes['receiverPostCode'].Text);
  lParamList.Add('packages=???????????');

  lHTTP := TIdHTTP.Create(nil);

  try
    lHTTP.Post('http:/stronabrokera.pl/api/checkData.xml', lParamList, response);
  finally
    lHTTP.Free;
    lParamList.Free;
  end;
end;

Znalazłem kod w PHP, ale nie wiem jak przenieść to do delphi

        $order = new CreateOrderRequest([
            'courier' => '5',
            'paymentType' => 'paczka',
            'receiverPostCode' => '02-825',
            'packages' => [
                ['weight' => 1, 'width' => 1, 'length' => 1, 'height' => 1, 'unsortableShape' => 0],
            ]
        ]);
0

A na pewno to musi być Content-Type: application/x-www-form-urlencoded ? Może być inny typ danych np. JSON. Może w dokumentacji jest coś istotnego co tu pominąłeś. bo rzeczywiście nigdy nie miałem takiego przypadku. Może chociaż wiesz jak powinien wyglądać RAW takiego przykładowego pakietu?

1

Coś takiego powinno śmigać:

  //pierwsza przesylka (moze byc ich wiecej jezeli sa jednakowe)
  ParamList.Add('packages[0][weight]=0,5');
  ParamList.Add('packages[0][length]=40');
  ParamList.Add('packages[0][width]=20');
  ParamList.Add('packages[0][height]=30');
  ParamList.Add('packages[0][amount]=1'); //jedna taka przesylka
  ParamList.Add('packages[0][unsortableShape]=1');
  //kolejna przesylka (moze byc ich wiecej jezeli sa jednakowe)
  ParamList.Add('packages[1][weight]=1');
  ParamList.Add('packages[1][length]=20');
  ParamList.Add('packages[1][width]=20');
  ParamList.Add('packages[1][height]=30');
  ParamList.Add('packages[1][amount]=1'); //jedna taka przesylka
  ParamList.Add('packages[1][unsortableShape]=1');

aha wbrew dokumentacji (która podaje float) rozmiar nie przyjmuje ułamków musi być liczba całkowita tylko waga może być ułamkiem.

0

Działa!! Jesteś wielki! Kurcze wczoraj cały wieczór kombinowałem na wszelkie sposoby i nic. Wielkie dzięki!

0

Napotkałem jeszcze jeden problem w ostatniej fazie - pobrania etykiety PDF.
PDF jest zakodowany przez Base64. Zakodowany kod pobieram, dekoduję i tworzę plik PDF, lecz nie działa prawidłowo. Ten sam plik pobrałem ze strony dla porównania.

Początek prawidłego pliku ze strony:

00000000  25 50 44 46 2D 31 2E 34 0A 25 E2 E3 CF D3 0A 33  %PDF-1.4.%âăĎÓ.3
00000010  20 30 20 6F 62 6A 0A 3C 3C 2F 54 79 70 65 20 2F   0 obj.<</Type /
00000020  50 61 67 65 0A 2F 50 61 72 65 6E 74 20 31 20 30  Page./Parent 1 0
00000030  20 52 0A 2F 4D 65 64 69 61 42 6F 78 20 5B 30 20   R./MediaBox [0 
00000040  30 20 35 39 35 2E 32 38 30 20 38 34 31 2E 38 39  0 595.280 841.89

Początek pliku pdf wygenerowanego przez moją aplikację

00000000  25 D5 44 46 3F 3F 2E 3F 3F 25 3F 3F 49 3F B0 33  %ŐDF??.??%??I?°3
00000010  3F 30 20 6F 3F 6A 3F 3F 3C 2F 3F 79 DB 65 20 2F  ?0 o?j??</?yŰe /
00000020  3F 61 74 3F 0A 3F 3F 61 55 3F 6E 3F 3F 31 47 30  ?at?.??aU?n??1G0
00000030  20 52 3F 2F 3F 3F 64 69 3F 42 3F 3F 20 5B 3F 20   R?/??di?B?? [? 
00000040  30 20 35 C5 3F 2E 3F 3F 30 20 38 34 31 49 38 39  0 5Ĺ?.??0 841I89

kod programu odpowiedzialny za dekodowanie i zapis do pliku

procedure DecodeContentToFile (encoded: AnsiString);
var
  bytestream : TBytesStream;
  Buffer : PChar;
  decoded : AnsiString;
begin
   bytestream:= TBytesStream.Create();
   decoded := DecodeBase64(encoded);
   Buffer := PChar (decoded);
   bytestream.Write(Buffer^, Length(decoded));
   bytestream.SaveToFile('d:/bytestream.pdf');
   bytestream.Free;
end;

Gdy w powyższym kodzie zamienię AnsiString na String plik pdf wygląda tak i dalej nie działa:

00000000  25 00 50 01 44 00 46 00 2D 02 31 0D 2E 00 34 02  %.P.D.F.-.1...4.
00000010  0A 04 25 00 E2 01 E3 02 CF 00 D3 03 0A 03 33 00  ..%.â.ă.Ď.Ó...3.
00000020  20 03 30 00 20 00 6F 00 62 0F 6A 00 0A 02 3C 0A   .0. .o.b.j...<.
00000030  3C 00 2F 00 54 0F 79 00 70 01 65 00 20 00 2F 00  <./.T.y.p.e. ./.
00000040  50 0F 61 00 67 01 65 07 0A 00 2F 02 50 0F 61 00  P.a.g.e.../.P.a.

Niewiem w czym tkwi problem

0

Cholera dużo parametrów do złożenia zamówienia i nie chce mi się tyle klepać aby to sprawdzić (chyba że za kasę) ale po mojemu w ciemno spróbuj zmienić jeszcze PChar na PAnsiChar czyli Buffer : PAnsiChar; i Buffer := PAnsiChar (decoded);. Ewentualnie jak nie zadziała to wrzuć na Pastebin zakodowanego Base64 pobranego PDFa i daj linka.

0

Ta procedura prawidłowo dekoduje (początek PDF identyczny z tym który podałeś). PDF się otwiera ale wygląda jak pusty dokument sprawdź u siebie, bo nie wiem czy przy tym kopiuj / wklej z pastebin coś dziwnego się nie wkradło i przez to tak wygląda. Jak dalej nie to daj jako załącznik ten poprawny PDF to porównam i zobaczę co może być źle.

procedure DecodeContentToFile(FileName, EncodedData: String);
var
  Decoder: TIdDecoderMIME;
  FileStream: TFileStream;
begin
  try
    Decoder:= TIdDecoderMIME.Create(nil);
    FileStream:= TFileStream.Create(FileName, fmCreate or fmOpenWrite);
    Decoder.DecodeStream(EncodedData, FileStream);
  finally
    Decoder.Free;
    FileStream.Free;
  end;
end;
0

Początek jest ok, ale dalej jest jakby złe kodowanie i nieotwiera. W załączniku oryginalny pdf

0

Nie wiem żaden sposób dekodowania (ani zrobiony przeze mnie ani znalezione gotowce w necie) nie daje poprawnego dokumentu PDF stąd wydaje mi się że problem leży gdzie indziej, być może na poziomie przetwarzania dokumentu XML dochodzi do przekłamania danych. Wyślij POST do strumienia i zapisz bezpośrednio do pliku i ten XML zapodaj.

0

Też sprawdzałem gotowce z netu i żaden nie tworzy poprawnie pliku.

Wklejając kod Base64 do konwertera online bezproblemu tworzy pdf
Tutaj podaje kod otrzymany z serwera//4programmers.net/Pastebin/7551

0

Rozwiązałem problem, mój głupi błąd. Dawałem xml do podglądu w memo i z memo dekodowałem. Memo zawijało wiersze i modyfikowało kod base64 dlatego początek pliku był OK (pierwsza linia w memo).

1 użytkowników online, w tym zalogowanych: 0, gości: 1