Я хотел бы интегрироваться с REST API ChannelAdvisor с использованием Поток учетных данных SOAP.
Основываясь на их документации, я настроил следующее в PostMan
(оставшийся клиент в браузере Chrome) вот так:
Когда я делаю отдых; сервер остальных API возвращает ожидаемый ответ:
Итак, я попытался повторить это в PHP с помощью следующего класса:
<?php
class ChannelAdvisorREST {
/**
* ChannelAdvisor constants & properties
*/
const BASE_URL = 'https://api.channeladvisor.com/v1';
private $config;
/**
* Class constructor
*/
public function __construct()
{
$this->config = \Config::get('channeladvisor');
}
// TEST
public function test($accountId)
{
// var_dump($this->config);
var_dump(self::getAccessToken($accountId));
}
// TEST
/**
* Method to get access token from rest server.
*
* @param $accountId
* @return string
*/
private function getAccessToken($accountId)
{
return self::curlPOST('/oauth2/token', [
'client_id' => $this->config['api_app_id'],
'grant_type' => 'soap',
'scope' => 'inventory',
'developer_key' => $this->config['api_developer_key'],
'password' => $this->config['api_password'],
'account_id' => $accountId
]);
}
/**
* Method to generate a HTTP POST request
*
* @param $endpoint
* @param $fields
* @return string
*/
private function curlPOST($endpoint, $fields = array())
{
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_USERPWD, $this->config['api_app_id'] .':'. $this->config['api_shared_secret']);
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . $endpoint);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields, '', '&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded'
));
// Execute post request
$result = curl_exec($ch);
// Close connection
curl_close($ch);
// Finished
return $result;
}
}
Когда я выполню тест ($ accId) Метод этого класса, я получаю следующий ответ:
Любая идея, почему это не совсем так же, как PostMan
тестовое задание?
Постскриптум Я уже проверил, что все конфиги / пармы и т. Д. Верны и соответствуют моему тесту PostMan. Этот класс является отрывочной версией из моего исходного кода (созданного в Laravel 4.2, но эта проблема не связана с Laravel).
Две вещи:
Убедитесь, что вы отправляете те же заголовки, что и ваш браузер. Например, я не вижу заголовка Authorization в вашем коде, и он, вероятно, весьма важен для авторизации запроса на стороне сервера. Также для сферы вы используете «инвентарь» вместо «заказывает инвентарь». Будьте очень строги в этом упражнении.
Протестируйте пост-данные не в массиве, а запишите строку запроса в соответствии с вашими потребностями. Таким образом, вы знаете, что CURL не пытается преобразовать ваш массив в строку запроса, так как вы знаете, что возможно для CURL, массива и строки запроса).
Так что проще всего проверить с:
client_id=1234&grant_type=soap&scope=order%20inventory...etc add other variables...
Я нашел проблему. Проблема была вызвана тем, что мой php не был настроен с curl.cainfo
,
Я нашел это, добавив следующий код отладки в мой curlPOST
метод как это:
private function curlPOST($endpoint, $fields = array())
{
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_USERPWD, $this->config['api_app_id'] .':'. $this->config['api_shared_secret']);
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . $endpoint);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields, '', '&'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded'
));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
// Execute post request
$result = curl_exec($ch);
// Debug error
if ($result === FALSE) {
printf("cUrl error (#%d): %s<br>\n", curl_errno($ch), htmlspecialchars(curl_error($ch)));
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
}
@fclose($verbose);
// Close connection
curl_close($ch);
// Finished
return $result;
}
Это вывело следующее сообщение об ошибке:
cUrl error (#60): SSL certificate problem: unable to get local issuer certificate
Verbose information:
* Hostname was found in DNS cache
* Hostname in DNS cache was stale, zapped
* Trying 216.27.89.14...
* Connected to api.channeladvisor.com (216.27.89.14) port 443 (#7)
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 7
boolean false
Который помог мне отследить проблему с моим php.