Seite 1 von 1

PHP, fstockopen und API

Verfasst: 24.06.2021, 09:04
von Wirths Media
Hallo,

derzeit bin ich am schreiben einer Schnittstelle (API) für einen Rechnungsupload zu Mirakl. Leider funktioniert dies nicht und ich kann mit keinen Reim daraus machen. Die Schnittstelle selbst scheint zu funktionieren und "andere Werte" über GET können ohne Probleme abgeholt werden.

Vielleicht hat jemand schon ein ähnliches Problem gehabt und kann mit dabei helfen.

Ach ja der Server antwortet mit 400...

Vielen Dank.

Code: Alles auswählen

function uploadInvoiceToServer ($invoice, $invoiceFilename, $order_id) {
    global $host, $apiKey;

    $boundary = "---------------------".substr(md5(rand(0,32000)),0,10);

    $invoiceFilename = trim(strstr($invoiceFilename, ' '));

    $documents['order_documents'][0] = ['file_name' => $invoiceFilename, 'type_code' => 'CUSTOMER_INVOICE'];

    $json = json_encode($documents);

    $dataToSend = "--$boundary\r\n";
    $dataToSend .= "Content-Disposition: form-data; name=\"files\"; filename=\"$invoiceFilename\"\r\n";
    $dataToSend .= "Content-Type: application/pdf\r\n\r\n";
    $dataToSend .= "$invoice\r\n";
    $dataToSend .= "--$boundary\r\n";
    $dataToSend .= "Content-Disposition: form-data; name=\"order_documents\"\r\n";
    $dataToSend .= "Content-Type: application/json\"\r\n\r\n";
    $dataToSend .= "$json\r\n";
    $dataToSend .= "--$boundary--\r\n";


    $fp = fsockopen("ssl://$host", 443, $errno, $errstr, 30);

    if (!$fp) {
        echo "$errstr ($errno)<br>\n";
    } else {
        $out .= "POST /api/orders/$order_id/documents HTTP/1.0\r\n";
        $out .= "Host: $host\r\n";
        $out .= "Authorization: $apiKey\r\n";
        $out .= "Content-Type: multipart/form-data; boundary=$boundary\r\n";
        $out .= "Content-Length: " . strlen($dataToSend) . "\r\n";
        $out .= "Connection: Close\r\n\r\n";

        fwrite($fp, $out);
        fwrite($fp, $dataToSend);

        while (!feof($fp)) {
            $data .= fgets($fp, 1024);
        }

        fclose($fp);

echo '<pre>';
var_dump($out.$dataToSend);
var_dump($data);
    return false;
    }
}

Code: Alles auswählen

POST /api/orders/{oder_id}/documents HTTP/1.0
Host: xxxx
Authorization: xxxxxxxxxxxxxxxx
Content-Type: multipart/form-data; boundary=---------------------1aaa7438a5
Content-Length: 256369
Connection: Close

-----------------------1aaa7438a5
Content-Disposition: form-data; name="files"; filename="99202421.pdf"
Content-Type: application/pdf


%PDF-1.3
3 0 obj
<>
endobj
4 0 obj
<>
stream
x��VKsG��W�%Uq ��=;�A   ˒-
________________________________________
�T�
…
[PDF DOKUMENT usw.…]
-----------------------1aaa7438a5
Content-Disposition: form-data; name="order_documents"
Content-Type: application/json"

{"order_documents":[{"file_name":"99202421.pdf","type_code":"CUSTOMER_INVOICE"}]}
-----------------------1aaa7438a5--

Sowie die Antwort vom Server....

Code: Alles auswählen

HTTP/1.1 400 Bad Request
Date: Tue, 22 Jun 2021 15:23:19 GMT
Content-Type: application/json
Content-Length: 49
Connection: close
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Expires: 0
Mirakl-Shop-Uuid: xxx
Mirakl-User-Role: SHOP
Original-Username: -
Pragma: no-cache
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Content-Type-Options: nosniff
X-Correlation-Id: f057e5e8-e81d-4f74-82e2-7085c502b29e
X-Frame-Options: DENY
X-Xss-Protection: 1; mode=block

{
  "message" : "Bad Request",
  "status" : 400
}

POST OR74 - Upload documents to attach to an order
Url
/api/orders/{order_id}/documents
Description

Upload documents to attach to an order

Documents filenames must be distinct. Only documents of the following types are supported: csv, doc, xls, xlsx, ppt, pdf, odt, ods, odp, txt, rtf, png, jpg, gif, zpl, mov, mp4.
An order can have a maximum of 50 documents. In the API output we include only documents with errors. All other documents are successfully uploaded.

Recommended: At each document upload on an order
Maximum: At each document upload on an order
Path parameters
order_id
required
string
The identifier of the order
Query parameters
shop_id
optional
integer - int64
Use this parameter when your user has access to several shops. If not specified, the shop_id from your default shop will be used.
HTTP Return Codes

200 - OK
Input (body)
Hide multipart/form-data input
files
required
array[string - binary]
The files to be uploaded. Use multipart/form-data with name 'files'. The file names must contain only US-ASCII characters.
order_documents
required
object Hide child attributes
The list of documents to be uploaded details
order_documents
required
array[object] Show child attributes
-

xml
json

{
"order_documents": [
{
"file_name": "filename1.txt",
"type_code": "CUSTOMER_INVOICE"
},
{
"file_name": "filename2.txt",
"type_code": "CUSTOMER_INVOICE"
}
]
}

Output (response)
Show application/json output
Show application/xml output
Response
Example with business values (application/json)

{
"errors_count": 1,
"order_documents": [
{
"errors": [
{
"code": "valid_order_document.type",
"field": "type_code",
"message": "Unable to retrieve document's type from the given code"
}
],
"input": {
"file_name": "customer-invoice-38294.pdf",
"type_code": "CUSTOSMER_INVOICE"
}
}
]
}

Example with business values (application/xml)
Complete example with value types (application/json)
Complete example with value types (applica

Verfasst:
von

Re: PHP, fstockopen und API

Verfasst: 24.06.2021, 12:56
von staticweb
Könnte es daran liegen?

"type_code": "CUSTOSMER_INVOICE"

Re: PHP, fstockopen und API

Verfasst: 24.06.2021, 14:04
von Wirths Media
Leider nein, aber danke.

Der letzte Abschnitt ist die Schnittstellenbeschreibung auf der Internetseite, API.

Als Beschreibung hier ist das als Rückgabe angegeben :)

Re: PHP, fstockopen und API

Verfasst: 24.06.2021, 14:23
von staticweb
Dann sprich den endpoint mal direkt über curl an, ohne ein attachment auszuwählen. Wenn das auch nicht klappt, bzw. keine konkrete Fehlermeldung zurückgegeben wird, würde ich mal den Anbieter kontaktieren.

Re: PHP, fstockopen und API

Verfasst: 24.06.2021, 14:42
von Wirths Media
Danke. Mit dem bin ich auch gerade im "Gespräch", ich würde jedoch eine Version über fsockopen bevorzugen...

Habe gerade diesen Code bekommen, welcher funktioniert...

Code: Alles auswählen

<?php

$jsonContent = "{
 \"order_documents\": [
          {
 \"file_name\": \"filename.pdf\",
 \"type_code\": \"CUSTOMER_INVOICE\"
          }
]}";

$tempJsonFile = tmpfile();
fwrite($tempJsonFile, $jsonContent);

$curl = curl_init();
curl_setopt_array($curl, [
 CURLOPT_URL => "http://XXXX/api/orders/XXXX/documents",
 CURLOPT_RETURNTRANSFER => 1,
 CURLOPT_POST => 1,
 CURLOPT_POSTFIELDS => array(
 "files" => new CURLFile("/tmp/filename.pdf", "application/pdf", "filename.pdf"),
 "order_documents" => new CURLFile(stream_get_meta_data($tempJsonFile)['uri'], "application/json")
    ),
 CURLOPT_HTTPHEADER => array(
 'Authorization: REDACTED'
 )
]);

$result = curl_exec($curl);

curl_close($curl);

echo '<pre>';
print_r($result);
echo '</pre>';

fclose($tempJsonFile);

Verfasst:
von

Re: PHP, fstockopen und API

Verfasst: 24.06.2021, 15:58
von Wirths Media
Problem 1 ist denke ich schon mal gelöst, hier im cURL Beispiel werden beide Daten in Files gepackt, dies habe ich gemacht. Leider noch immer nicht ganz richtig.

Ich denke momentan, dass die Daten noch aufbereitet werden müssen?