jlevers / selling-partner-api

A PHP client library for Amazon's Selling Partner API
BSD 3-Clause "New" or "Revised" License
397 stars 185 forks source link

I can't upload Invoice #519

Open Kernel1453 opened 1 year ago

Kernel1453 commented 1 year ago

Dear All, I'm trying to upload invoice but I'm getting error below

[400] {
  "errors": [
    {
      "code": "InvalidInput",
      "message": "Attachment with ID 62797d05-a812-4ce1-9315-d596b82e6114 does not exist",
      "details": ""
    }
  ]
}

What I'm trying to do is

$request->validate([
                    'file' => 'nullable|file'
                ]);
                $data = null;

                if ($request->hasFile('file')) {
                    $this->addFileDetail($request, $saveMessage, 'file');

                    $attachment = $this->attachments($request, $config, $amazonOrderId, $marketplaceIds, 'file',
                        'invoice');
                    $data['attachments'] = $attachment;
                }

                $body = new InvoiceRequest($data);
                try {
                    $result = $apiInstance->sendInvoice($amazonOrderId, $marketplaceIds, $body);
                    print_r($result);
                } catch (\SellingPartnerApi\ApiException $e) {
                    dd($e->getMessage());

                    $result = 'Exception sendInvoice: ' . $e->getMessage() . PHP_EOL;
                }
protected function attachments($request, $config, $amazonOrderId, $marketplaceIds, $fileName, $messageType = null)
    {
        if ($request->hasFile($fileName)) {
            $uploadApi = new UploadsV20201101Api($config);
            $file = base64_encode(file_get_contents($request->file($fileName)->path()));
            $md5Content = md5($file, false);
            $destination = 'messaging/v1/orders/' . $amazonOrderId . '/messages/' . $messageType ?? $request->mesage_type;
            $result = $uploadApi->createUploadDestinationForResource($marketplaceIds, $md5Content, $destination);
            $resultPayload = $result->getPayload();
            $attachment = new Attachment([
                'upload_destination_id' => $resultPayload['upload_destination_id'],
                'file_name' => $request->mesage_type . $amazonOrderId . '.' . $request->file($fileName)->extension()
            ]);

            return [$attachment];
        }
    }
protected function addFileDetail($request, $saveMessage, $fileName)
    {
        $saveMessage['file_name'] = $request->file($fileName)->getClientOriginalName();
        $saveMessage['file_extension'] = $request->file($fileName)->getClientOriginalExtension();
    }

where i am making mistake, could you please help asap? Thank you. Best Regards

Kernel1453 commented 1 year ago

Hi All, Do you know any solution to overcome this, we are still trying this. @jlevers

jlevers commented 1 year ago

@Kernel1453 what is the full response you get when you call createUploadDestinationForResource?

jlevers commented 1 year ago

Closing due to inactivity. If you still need support on this, let me know and I'll reopen it.

Kernel1453 commented 1 year ago

Hello, still cant overcome this and need support.

jlevers commented 1 year ago

Please answer my previous question so that I can help you:

@Kernel1453 what is the full response you get when you call createUploadDestinationForResource?

Kernel1453 commented 1 year ago

@jlevers Return message is same.

[400] { "errors": [ { "code": "InvalidInput", "message": "Attachment with ID XXXXXX does not exist", "details": "" } ] }

jlevers commented 1 year ago

So the error is happening before you get to the sendInvoice call? Have you ever reached that call?

Kernel1453 commented 1 year ago

@jlevers No, never. I always Got same error in same point.

jlevers commented 1 year ago

What does your $destination variable contain if you var_dump it right before the createUploadDestinationForResource call?

Kernel1453 commented 1 year ago

@jlevers Hi, thank you for reply my message. this is my var_dump => string(56) "messaging/v1/orders/406-1310933-XXXXXXX/messages/invoice"

and when i send file returns

{ "message": "Client error: `POST https://sellingpartnerapi-eu.amazon.com/messaging/v1/orders/406-1310933-XXXXXXX/messages/invoice?marketplaceIds=A33AVAJ2PDY3EV` resulted in a `400 Bad Request` response:\n{\n \"errors\": [\n {\n \"code\": \"InvalidInput\",\n \"message\": \"Attachment with ID 083a7d5a-b617-4473-b03c-2d52cb1 (truncated...)\n", "exception": "GuzzleHttp\\Exception\\ClientException", "file":

here error is Attachment with ID doesnt exist.

Could you please check my code below about MD5 hashing and other methods are correct or need to be fixed? again thank you very much.

 if ($request->hasFile($fileName)) {
            $uploadApi = new UploadsV20201101Api($config);
            $fileContents = $request->file($fileName)->get();
            $md5Content = md5($fileContents,true);
            $destination = 'messaging/v1/orders/' . $amazonOrderId . '/messages/' . $messageType ?? $request->mesage_type;
            $result = $uploadApi->createUploadDestinationForResource($marketplaceIds, $md5Content, $destination);
            $resultPayload = $result->getPayload();
            $url = $resultPayload->getUrl();
            $headers = $resultPayload->getHeaders();
            $headers['Content-MD5'] = base64_encode(md5($fileContents,true));

            $headers['Content-Type'] = 'Binary';
            $filename = $messageType . $amazonOrderId . '.' . $request->file($fileName)->extension();
            $response = Http::attach(
                'attachment', $fileContents, $filename,$headers
            )->withHeaders($headers)->put($url);

          //  dd($response->getBody()->getContents());
            $attachment = new Attachment([
                'upload_destination_id' => $resultPayload['upload_destination_id'],
                'file_name' => $filename
            ]);

          //  dd($attachment);
            return [$attachment];
        }

best regards

Kernel1453 commented 1 year ago

We still have this issue. Now getting yoursignature doesnt match. What should we do? Please help @jlevers

jlevers commented 1 year ago

I'm not positive about this, but I think you need a leading slash in your $destination string (so /messaging/v1/orders/406-1310933-XXXXXXX/messages/invoice instead of messaging/v1/orders/406-1310933-XXXXXXX/messages/invoice).

If that doesn't solve the problem, I recommend contacting Amazon support – I don't use this API so it's hard for me to know what the issue is.

Kernel1453 commented 1 year ago

hi @jlevers when i use /messaging, at this time i get

"message": "[403] {\n \"errors\": [\n {\n \"code\": \"Unauthorized\",\n \"message\": \"Access to requested resource is denied.\",\n \"details\": \"\"\n }\n ]\n}", "exception": "SellingPartnerApi\ApiException",

jlevers commented 1 year ago

Do you have the Buyer Communication role?

Kernel1453 commented 1 year ago

@jlevers yes, i have all the roles including the buyer communication role. I can use createUnexpectedProblem and can get all orders & updates.

jlevers commented 1 year ago

Weird, ok. I recommend opening a support case with Amazon, because I don't have any further insight into this, and I'm 99% sure it's an API issue, not an issue with this library.

Kernel1453 commented 1 year ago

@jlevers thank you very much. I will open a case and inform you.