Trisse
Trisse

Reputation: 1

Unable to solve bad request error when trying to post to Microsoft Business Central using PHP

I am trying to create a new customer in business central with my website. I am able to do it using Postman without any errors. When I try to run a post request using PHP I get a 400 bad request error. I am not that familiar with PHP so I am hoping there is something obvious that I am missing.

My code:

$url = "https://api.businesscentral.dynamics.com/v2.0/ ". $tennantId ."/Production/api/v2.0/customers";

        $content = array(
            "displayName" => $obj->displayName,
            "addressLine1" => $obj->addressLine1,
            "addressLine2" => $obj->addressLine2,
            "city" => $obj->city,
            "state" => $obj->state,
            "country" => $obj->country,
            "postalCode" => $obj->postalCode,
            "email" => $obj->email,
            "currencyCode" => $obj->currencyCode
        );

        $options = array(
            "http" => array(
                "header" => "Content-Type: application/json\r\n" .
                "Authorization: Bearer " . $accessToken . "\r\n",
                "method" => "POST",
                "content" => json_encode($content)
            )
        );

        $context = stream_context_create($options);
        $json = file_get_contents($url, false, $context);

        $data = json_decode($json, true);

Edit:

I tried using cURL to send the POST request and I don't get any errors. The request return a 200 but the customer isn't created in the Business Central. I shall try to compare my request with the one Postman sends to see if I am missing something.

$ch = curl_init($url);
# Setup request to send json via POST.
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer ' . $accessToken));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($content));
# Return response instead of printing.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
# Send request.
$data = curl_exec($ch);
if (curl_errno($ch)) {
  $error_msg = curl_error($ch);
}
curl_close($ch);

// Do something with the $data response
var_dump($data);

Upvotes: 0

Views: 685

Answers (2)

Trisse
Trisse

Reputation: 1

Thank you for your suggestions! I was able to look at the code that Postman generated (I did not know this was possible) and compared it to my own. Now I know that the problem is because of the country and email fields. This will require a bit of troubleshooting but I should be able to do this on my own. Thank you to everyone for your suggestions!

Code generated by Postman and edited to fit my code:

        $content = array(
            "displayName" => $obj->displayName,
            "addressLine1" => $obj->addressLine1,
            "addressLine2" => $obj->addressLine2,
            "city" => $obj->city,
            "state" => $obj->state,
            // "country" => $obj->country,
            "postalCode" => $obj->postalCode,
            // "email" => $obj->email,
            "currencyCode" => $obj->currencyCode
        );

        $curl = curl_init();

        curl_setopt_array(
            $curl,
            array(
                CURLOPT_URL => "https://api.businesscentral.dynamics.com/v2.0/" . $tennantId . "/Production/api/v2.0/customers",
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => "",
                CURLOPT_MAXREDIRS => 10,
                CURLOPT_TIMEOUT => 0,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_POSTFIELDS => json_encode($content),
                CURLOPT_HTTPHEADER => array(
                    "Content-Type: application/json",
                    "Authorization: Bearer " . $accessToken,
                ),
            )
        );

        $response = curl_exec($curl);

        curl_close($curl);

        // Do something with the $data response
        var_dump($response);

Upvotes: 0

kaspermoerch
kaspermoerch

Reputation: 16570

The first thing I notice is that you are missing the companies part in your URL.

This means that Business Central does not know which company the customer should be created in.

The correct form of the URL is:

$url = "https://api.businesscentral.dynamics.com/v2.0/". $tennantId ."/Production/api/v2.0/companies([Company GUID])/customers";

To get the Company GUID you can call the companies endpoint to get the list of available companies which would be this URL:

$url = "https://api.businesscentral.dynamics.com/v2.0/". $tennantId ."/Production/api/v2.0/companies";

Upvotes: 1

Related Questions