0

I am using Mirakl api. I faced an issue with the file upload with form-peram in Laravel 8 external api with guzzle or HTTP client.I got 400 Bad Request.The api expects file with from-param like this

{
  "order_documents": [{
    "file_name": String,
    "type_code": String
  }]
 } 

The documentation of my endpoint can be found from this link (http://185.29.149.41/eci/mir/doc/api/OR74.html) and here is my codes --

public function upload_order(Request $request)
{
    $order_id = $request->order_id;
    if ($files = $request->file('files')) {
         $name = $files->getClientOriginalName();
         Storage::disk('invoice')->put($name, file_get_contents($files->getRealPath()));
         $path = Storage::disk('invoice')->path($name);
    }
    $file['order_documents'][] = [
           'file_name' => $name,
           'type_code' => $request->type_code,
    ];
    $json = json_encode($file);
    $data = [
         ['name' => 'order_documents','contents' => $json],
    ];
    $data[] = [
         'name' => 'files',
         'contents' => mb_convert_encoding($path, 'UTF-8', 'UTF-8'),
         'filename' => $name,
    ];
    $body['multipart'] = $data;
    $configApi = $this->configApi($this->getMarketplaceID($request->marketplace), auth()->user()->id);
    $url = $configApi['url'].'/api/orders/'.$order_id.'/documents';
    $client = new Client(['verify' => false]);
    $response = $client->request(
                'POST',
                $url,
                [
                    'multipart' => $data,
                    'headers' => $configApi['headers']
                ]);
    return json_decode($response->getBody(), true);
}
  • I tried with various approaches but everytime got 400 error – Tanvir Hasan Jun 20 '22 at 13:20
  • welcome to so, your api clearly tells to use `Use multipart/form-data with name 'files'` – bhucho Jun 22 '22 at 09:06
  • also use try catch in calling requests take example from [this](https://stackoverflow.com/a/64603614/9471283) – bhucho Jun 22 '22 at 09:07
  • whats the content type header in here `'headers' => $configApi['headers']` – bhucho Jun 22 '22 at 09:08
  • is it a single file or multiple files – bhucho Jun 22 '22 at 09:09
  • @bhucho Thanks for your comment. I am using using the name of file as 'files' $data[] = [ 'name' => 'files', 'contents' => file_get_contents($files->getRealPath()), 'filename' => $name, ]; I have trided to catch the exception but didn't get anything except 400 error. this is endpoint is valid for both single and multiple files. right now, I am tring with single file – Tanvir Hasan Jun 22 '22 at 10:12
  • In the 'headers' I have this array `$headers = [ 'Accept' => '*/*', 'Accept-Encoding' => 'gzip, deflate, br', 'Cache-Control' => 'no-cache', 'Connection' => 'keep-alive', 'Authorization' => $marketPlaceInfo->api_key, 'Accept' => 'application/json', ];` – Tanvir Hasan Jun 22 '22 at 10:31
  • don't send these headers It seems you copied from browser or api tool, only send authorization now, 400 means bad request there are many reasons for a bad request you need to remove/ change all possible sources of error – bhucho Jun 22 '22 at 11:07
  • also why use ['verify' => false] ? you are sending authorization as well, so why? – bhucho Jun 22 '22 at 11:07
  • yes, I took the header from the Mirakl postman collection and ['verify' => false] is optional basically it disables ssl verification – Tanvir Hasan Jun 22 '22 at 11:51
  • there is another api endpoint regarding only file upload without any form-param, it works fine with the header and the codes, I just add additional info for $data for form-param for this api endpoint in which I currently faced issue – Tanvir Hasan Jun 22 '22 at 11:56
  • try ` if($e->hasResponse()){ if ($e->getResponse()->getStatusCode() == '400'){ $error['response'] = $e->getResponse(); } }` within the guzzle requestexception the example is there in the link I had sent above – bhucho Jun 22 '22 at 15:04
  • then we can know the exact error – bhucho Jun 22 '22 at 15:04
  • got this response `Error occurred in get request. {"error":{"error":"Client error: `POST https://kadewe-dev.mirakl.net/api/orders/Order_28Oct2021_1-A/documents` resulted in a `400 Bad Request` response: ` – Tanvir Hasan Jun 23 '22 at 09:03
  • use debug => true, refer here even hard for me to tell without trying code looks fine at a glance , refer [this](https://docs.guzzlephp.org/en/latest/request-options.html#debug) to know more about debug request option – bhucho Jun 23 '22 at 09:38
  • got this error message `"message": "curl_setopt_array(): Cannot represent a stream of type Output as a STDIO FILE*",` – Tanvir Hasan Jun 23 '22 at 10:01
  • it might be due to `$files->getRealPath()` getRealPath() does not give then correct path it gives the tmp path most of the times, Storage returns path so concat with the the filename and then use file_get_contents on it – bhucho Jun 23 '22 at 10:14
  • I changed the code now I am using this saved file `Storage::disk('invoice')->put($name, file_get_contents($files->getRealPath())); $path = Storage::disk('invoice')->path($name);` `$data[] = [ 'name' => 'files', 'contents' => mb_convert_encoding($path, 'UTF-8', 'UTF-8'), 'filename' => $name, ];` – Tanvir Hasan Jun 23 '22 at 10:23
  • use dd() to check whether you are getting file object in the path you have mentioned to the api – bhucho Jun 23 '22 at 12:04
  • I have the file name with exact path after dumping the $path – Tanvir Hasan Jun 23 '22 at 12:44
  • post your updated code here by editing the question – bhucho Jun 23 '22 at 13:56
  • already updated – Tanvir Hasan Jun 23 '22 at 14:41

0 Answers0