Pull to refresh

Работа с OZON (Merchants) API средствами PHP

Reading time 4 min
Views 22K
Работаем над большим интернет-магазином. И вот возникла необходимость из УТ (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);

Таким образом можно управлять заказами на Озон со своего сайта.

Надеюсь, моя статья будет кому-то полезной. Всем спасибо за внимание!

Кое-какая документация
Tags:
Hubs:
-2
Comments 2
Comments Comments 2

Articles