Работаем над большим интернет-магазином. И вот возникла необходимость из УТ (1С Управление торговлей) управлять заказами на O Ozon.
Смысл такой: есть БД PostgreSQL, 1C'ка работает с этой базой, вносит данные о поступивших заказах, меняет статусы заказов. И есть также скрипт PHP, который лежит на сервере и выполняется по крону каждые 3 минуты. Что этот скрипт должен делать?
- 1. Получать токен от API ozon;
- 2. Забирать все новые заказы с Ozon. Создавать новый XML файл с полученными заказами;
- 3. Получать из БД заказы с определённым статусом. Изменять статус этих заказов на Ozon. Изменять статус этих заказов в БД;
- 4. Закрывать заказы с определённым статусом на Ozon. Изменять статус этих заказов в БД.
С получением токена проблем не возникло. Воспользовавшись функцией file_get_contents(), я достиг желаемого.
// Получим токен /auth/token/merchants?applicationid=[ApplicationId] (ApplicationId )
// $sign - рассчитанная SHA1-HMAC подпись, где ключом будет секретный ключ приложения, а значением на подпись - path-часть URL
// Ответ json, например { "token": "9895DDA48379484ABC51A4B193CDAE04", "expiration": 600 }
$sign = hash_hmac('sha1','/auth/token/merchants?applicationid=albion','[секретный ключ приложения]');
$token = file_get_contents('https://api.ozon.ru/auth/token/merchants?applicationid=[ApplicationId]&sign='.$sign);
$token = substr($token,10,32);
Далее возникли проблемы. Вместе с запросом нужно было передавать заголовки. API документировано довольно плохо, примеры кода отсутствуют, в Гугле не нашёл ни одного примера. Пришлось работать методом проб и ошибок. Попробовал сначала действовать таким же образом через file_get_contents() — безрезультатно. Что бы я ни делал — выводилась ошибка, что невозможно создать канал.
В итоге воспользовался curl. Код получения списка новых созданных заказов (в json и в xml):
// Получаем список новых заказов в json
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.ozon.ru/merchants/orders?StateName=Создан');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"x-ApplicationId: [ApplicationId]",
"x-Token: ".$token,
"x-ApiVersion: 0.1"
));
$out = curl_exec($curl);
curl_close($curl);
// Получаем список новых заказов в xml
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.ozon.ru/merchants/orders?StateName=Создан');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"accept: application/xml",
"content-type: application/xml",
"x-ApplicationId: [ApplicationId]",
"x-Token: ".$token,
"x-ApiVersion: 0.1"
));
$out1 = curl_exec($curl);
curl_close($curl);
Моменты, связанные с созданием xml файла и изменениями в БД postgreSQL описывать тут не буду, ибо это уже будет отступлением от темы.
Далее нужно было изменить статус заказа. Для этого кроме всего прочего в теле PUT-запроса нужно было передать новый статус (как выяснилось путём долгих изысканий — в виде XML).
Смена статусов заказов выглядит следующим образом:
// Для каждого заказа меняем его статус
foreach($ids as $item)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.ozon.ru/merchants/orders/state/'.$item);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, "<OrderStateRequest><StateSysName>ClientOrderStateMerchantAccepted</StateSysName></OrderStateRequest>");
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"accept: application/xml",
"content-type: application/xml",
"x-ApplicationId: [ApplicationId]",
"x-Token: ".$token,
"x-ApiVersion: 0.1"
));
$out = curl_exec($curl);
curl_close($curl);
}
Для различных статусов нужно использовать разные XML данные. Приведу список всех доступных статусов:
<OrderStatesResponse>
<OrderStates>
<OrderState>
<Name>Создан</Name>
<SysName>ClientOrderStateMerchantCreated</SysName>
</OrderState>
<OrderState>
<Name>Ожидает оплаты</Name>
<SysName>ClientOrderStateMerchantAwaitingPayment</SysName>
</OrderState>
<OrderState>
<Name>Оплачен</Name>
<SysName>ClientOrderStateMerchantPaymentDone</SysName>
</OrderState>
<OrderState>
<Name>Принят продавцом</Name>
<SysName>ClientOrderStateMerchantAccepted</SysName>
</OrderState>
<OrderState>
<Name>Отправлен</Name>
<SysName>ClientOrderStateMerchantSent</SysName>
</OrderState>
<OrderState>
<Name>Выполнен</Name>
<SysName>ClientOrderStateMerchantDone</SysName>
</OrderState>
<OrderState>
<Name>Аннулирован</Name>
<SysName>ClientOrderStateMerchantCanceled</SysName>
</OrderState>
</OrderStates>
</OrderStatesResponse>
Также иногда возникает необходимость отмены заказа. Для этого нужно указать причину отмены (также в виде XML в теле запроса).
Приведу пример (указанная причина: «Число заказов больше, чем есть в наличии»):
// Меняем статус на озоне
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.ozon.ru/merchants/orders/state/'.$order_number);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, "<OrderStateRequest><StateSysName>ClientOrderStateMerchantCanceled</StateSysName><CancelReason>OrderCountMoreThanRest</CancelReason></OrderStateRequest>");
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"accept: application/xml",
"content-type: application/xml",
"x-ApplicationId: [ApplicationId]",
"x-Token: ".$token,
"x-ApiVersion: 0.1"
));
$out = curl_exec($curl);
curl_close($curl);
Таким образом можно управлять заказами на Озон со своего сайта.
Надеюсь, моя статья будет кому-то полезной. Всем спасибо за внимание!
Автор: GodManfred