Яндекс.Доставка работа с API в PHP

Примеры работы с API Яндекс.Доставки (для заказа перевозки грузов корпоративным клиентам).

Документация на https://yandex.ru/dev/logistics/api/about/intro.html

Для доступа к API Яндекс.Доставки понадобится OAuth-токен, получить его можно в личном кабинете.

Данный метод создает заявку с переданными параметрами. Заявка попадает в систему логистики и запускает процесс заказа. Отправка запроса не начинает обработку заказа, подробнее на https://yandex.ru/dev/logistics/api/ref/v2/claims/IntegrationV2ClaimsCreate.html

Для формирования заказа возьмем два массива, $order – данные о заказе и $prods – список заказанных продуктов:

// Данные заказа:
$order = array(
	'id'            => 123456,
	'name'          => 'Иван Петров',
	'address'       => 'г.Москва, ул.Тверская, д.23',
	'phone'         => '+7 (905) 123-45-67',
	'comment'       => '3й этаж',
	'delivery_date' => '17.09.2021 10:00',
);

// Заказанные продукты:
$prods = array(
	array(
		'id'      => 1,
		'name'    => 'Сок',
		'price'   => 100.0,
		'count'   => 1,
	),
	array(
		'id'      => 2,
		'name'    => 'Маффин',
		'price'   => 200.0,
		'count'   => 2,
	)
);
PHP

Далее понадобится функция для генерации токена идемпотентности (просто уникальный набор символов). Допускаются буквы, цифры, другие символы.

function gen_uuid() {
	return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
		mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
		mt_rand( 0, 0xffff ),
		mt_rand( 0, 0x0fff ) | 0x4000,
		mt_rand( 0, 0x3fff ) | 0x8000,
		mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
	);
}
PHP

Так-же понадобится ключ для Геокодера API Яндекс.Карт т.к. в запросе нужно передать координаты адреса доставки.

// Получаем координаты адреса доставки:
$ch = curl_init('https://geocode-maps.yandex.ru/1.x/?apikey=КЛЮЧ&format=json&geocode=' . urlencode($order['address']));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);

$res = json_decode($res, true);
$coordinates = explode(' ', $res['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']['Point']['pos']);
foreach($coordinates as $i => $r) {
	$coordinates[$i] = floatval($r);
}
$coordinates = array_shift($coordinates);
PHP

И последний момент – нужно привести телефон к формату +7XXXXXXXXXX.

// Приводим телефон к формату +7XXXXXXXXXX
$phone = preg_replace('/[\s]/', '', $order['phone']);
$phone = preg_replace('/[^0-9\+]/', '', $phone);
$phone = ltrim($phone, '+');
$phone = '+' . $phone;
PHP

Собираем все данные в один массив и отправляем:

// Формируем массив продуктов в заказе
$items = array();
foreach ($prods as $row) {
	$items[] = array(
		"cost_currency" => 'RUB',
		"cost_value"    => $row['price'],
		"pickup_point"  => 1,
		"droppof_point" => 2,
		"fiscalization" => array(
			"article"   => $row['id'],
			"item_type" => 'product',
		),
		"quantity" => $row['count'],
		"title"    => $row['name'],
	);
}

// Формируем общий массив
$data = array(
	"callback_properties" => array(
		"callback_url" => 'https://example.com/?', // URL, будет вызываться при смене статусов.
	),
	"client_requirements" => array(
		"cargo_loaders" => 0, 
		"pro_courier"   => false,
		"taxi_class"    => 'courier' // Класс такси. Значения: courier, express, cargo
	),
	"comment" => $order['comment'],
	"due" => date('c', $order['delivery_date']),
	"emergency_contact" => array(
		"name"  => $order['name'],
		"phone" => $phone
	),	
	"items" => $items,
	"optional_return" => false,
	"referral_source" => 'Источник заявки (можно передать наименование CMS)',
	"route_points" => array(
		// Откуда забрать заказ (точка А)
		array(
			"address" => array(
				"coordinates" => array(35.534901, 55.734963),
				"fullname"    => 'г. Москва, .....',
			),
			"contact" => array(
				"email" => '',
				"name"  => '',
				"phone" => ''
			),
			'point_id' => 1,
			'skip_confirmation' => true,
			'type' => 'source',
			'visit_order' => 1,
		),					
		// Куда доставить заказ (точка Б)
		array(
			"address" => array(
				"coordinates" => $coordinates,
				"fullname"    => $order['address'],
			),
			"contact" => array(
				"email" => '',
				"name"  => '',
				"phone" => ''
			),
			'point_id' => 2,
			'skip_confirmation' => true,
			'type' => 'destination',
			'visit_order' => 2,
		),
	),
	"shipping_document" => '',
	"skip_act" => true,
	"skip_client_notify" => false,
	"skip_door_to_door" => false,
	"skip_emergency_notify" => false
);

// Отправка:
$gen_uuid = gen_uuid();
$ch = curl_init('https://b2b.taxi.yandex.net/b2b/cargo/integration/v2/claims/create?request_id=' . $gen_uuid);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: ru', 'Authorization: Bearer ТОКЕН'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($req, JSON_UNESCAPED_UNICODE)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);

// Читаем ответ
$res = json_decode($res, true);
if (!empty($res['id'])) {
	//var_dump($res);
	echo '№ заказа: ' . $res['id'];
} else {
	echo $res['message'];
}
PHP

После того, как заказ был успешно отправлен в API, заявка проверяется и оценивается, после чего её нужно подтвердить. Делается это следующим запросом.

// Номер заявки в системе яндекса
$claim_id = 'xxx';

$ch = curl_init('https://b2b.taxi.yandex.net/b2b/cargo/integration/v1/claims/accept?claim_id=' . $claim_id);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: ru', 'Authorization: Bearer ТОКЕН'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('version' => 1), JSON_UNESCAPED_UNICODE)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
				
$res = json_decode($res, true);
echo 'Статус подтверждения: ' . $res['status'];
PHP

Чтобы получить текущий статус заказа, необходимо отправить следующий запрос:

// Номер заявки в системе яндекса
$claim_id = 'xxx';

$ch = curl_init('https://b2b.taxi.yandex.net/b2b/cargo/integration/v1/claims/info?claim_id=' . $claim_id);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Language: ru', 'Authorization: Bearer ТОКЕН'));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
	
$res = json_decode($res, true);

if ($res['status'] == 'new') {
	echo 'Создана';
} elseif ($res['status'] == 'estimating_failed') {
	echo 'Не удалось оценить заявку';	
} elseif ($res['status'] == 'ready_for_approval') {
	echo 'Готов к одобрению';
} elseif ($res['status'] == 'cancelled') {
	echo 'Отменен';
} else {
	echo $res['status'];
}
PHP

Все статусы на https://yandex.ru/dev/logistics/api/about/claims-status.html.

22.09.2021
2049

Комментарии

, чтобы добавить комментарий.

Другие публикации

Авторизация на сайте через Яндекс
Сервис Яндекс.Паспорт позволяет через API реализовать авторизацию пользователя на своем сайте. После разрешения доступа...
9928
+8
Прием платежей на сайте через Юкассу
В данной статье описан процесс оплаты через сервис ЮKassa с помощью прямых запросов к API через PHP cURL.
9376
+5
Интеграция с платежной системой PayKeeper в PHP
Платежная платформа PayKeeper позволяет принимать оплату заказов по ссылке, используя данный метод можно с легкостью...
5349
0
Подключение к платежной системе Сбербанка
После регистрации в системе эквайринга Сбербанка и получив доступ к тестовой среде, можно приступить к интеграции с...
46062
+20
Использование API Яндекс Диска на PHP
Можно найти множество применений Яндекс Диска на своем сайте, например, хранение бекапов и отчетов, обновление прайсов,...
42182
+15
Бот Телеграм на PHP
Примеры как зарегистрировать бота в Телеграм, описание и взаимодействие с основными методами API.
96022
+40