Skip to content

Instantly share code, notes, and snippets.

@andronex
Last active July 24, 2023 11:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andronex/87a4f9389096db0d911eca5491f52523 to your computer and use it in GitHub Desktop.
Save andronex/87a4f9389096db0d911eca5491f52523 to your computer and use it in GitHub Desktop.
MODX API для Яндекс Маркет плейсмаркета (Я.Маркет для партнёров) (MODX Revolution от 2.7.2-pl + miniShop2 от 2.5.0-pl)
<?php
/*
* API для Я.Маркет плейсмаркета
* by i.modx@ya.ru / andronex
* интеграция от 12 т.р.
*/
//шлём заголовки
header('Access-Control-Allow-Origin: *');
header('Content-type: application/json; charset=utf-8');
//единая функция вывода ошибок, по дефолту = 401 Unauthorized, вывод в JSON и прекращение работы
function getAccessDenied($detail = 'Access denied', $title = 'Access denied', $status = 401) {
$detail = json_encode($detail);
$title = json_encode($title);
$http_status_codes = array(100 => "Continue", 101 => "Switching Protocols", 102 => "Processing", 200 => "OK", 201 => "Created", 202 => "Accepted", 203 => "Non-Authoritative Information", 204 => "No Content", 205 => "Reset Content", 206 => "Partial Content", 207 => "Multi-Status", 300 => "Multiple Choices", 301 => "Moved Permanently", 302 => "Found", 303 => "See Other", 304 => "Not Modified", 305 => "Use Proxy", 306 => "(Unused)", 307 => "Temporary Redirect", 308 => "Permanent Redirect", 400 => "Bad Request", 401 => "Unauthorized", 402 => "Payment Required", 403 => "Forbidden", 404 => "Not Found", 405 => "Method Not Allowed", 406 => "Not Acceptable", 407 => "Proxy Authentication Required", 408 => "Request Timeout", 409 => "Conflict", 410 => "Gone", 411 => "Length Required", 412 => "Precondition Failed", 413 => "Request Entity Too Large", 414 => "Request-URI Too Long", 415 => "Unsupported Media Type", 416 => "Requested Range Not Satisfiable", 417 => "Expectation Failed", 418 => "I'm a teapot", 419 => "Authentication Timeout", 420 => "Enhance Your Calm", 422 => "Unprocessable Entity", 423 => "Locked", 424 => "Failed Dependency", 424 => "Method Failure", 425 => "Unordered Collection", 426 => "Upgrade Required", 428 => "Precondition Required", 429 => "Too Many Requests", 431 => "Request Header Fields Too Large", 444 => "No Response", 449 => "Retry With", 450 => "Blocked by Windows Parental Controls", 451 => "Unavailable For Legal Reasons", 494 => "Request Header Too Large", 495 => "Cert Error", 496 => "No Cert", 497 => "HTTP to HTTPS", 499 => "Client Closed Request", 500 => "Internal Server Error", 501 => "Not Implemented", 502 => "Bad Gateway", 503 => "Service Unavailable", 504 => "Gateway Timeout", 505 => "HTTP Version Not Supported", 506 => "Variant Also Negotiates", 507 => "Insufficient Storage", 508 => "Loop Detected", 509 => "Bandwidth Limit Exceeded", 510 => "Not Extended", 511 => "Network Authentication Required", 598 => "Network read timeout error", 599 => "Network connect timeout error");
header('HTTP/1.0 '.$status.' '.$http_status_codes[$status]);
//сброс сессий
@session_write_close();
die('{"errors": [
{
"status": '.$status.',
"title": '.$title.',
"detail": '.$detail.'
}
]}');
}
//функция определения расстояния между точками по их координатам
function getDistance($lat1, $lon1, $lat2, $lon2) {
$lat1 *= M_PI / 180;
$lat2 *= M_PI / 180;
$lon1 *= M_PI / 180;
$lon2 *= M_PI / 180;
$d_lon = $lon1 - $lon2;
$slat1 = sin($lat1);
$slat2 = sin($lat2);
$clat1 = cos($lat1);
$clat2 = cos($lat2);
$sdelt = sin($d_lon);
$cdelt = cos($d_lon);
$y = pow($clat2 * $sdelt, 2) + pow($clat1 * $slat2 - $slat1 * $clat2 * $cdelt, 2);
$x = $slat1 * $slat2 + $clat1 * $clat2 * $cdelt;
return atan2(sqrt($y), $x) * 6372795;
}
//если метода в теле не находим - die()
if(!isset($_REQUEST['method']) || $_REQUEST['method'] == '' || empty($_REQUEST['method'])) getAccessDenied();
//находим метод в запросе
$action = $_REQUEST['method']?:'';
$method = $_SERVER['REQUEST_METHOD']?:'GET';
// инициализация MODX API
define('MODX_API_MODE', true);
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/core/config/config.inc.php';
require_once MODX_BASE_PATH . 'index.php';
// Включаем обработку ошибок
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'FILE');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->getService('error','error.modError');
$modx->error->message = null;
if(!$ya_market_api = $modx->getOption('ya_market_api')){
getAccessDenied('Не задана настройка ya_market_api', 'Отсуствует API key', 403);
}
if(!$_REQUEST['auth-token'] || $_REQUEST['auth-token'] != $modx->getOption('ya_market_api')){
getAccessDenied('API key неверный', 'API key неверный', 403);
}
if(!$modx->getOption('ya_pickup_ids')){
getAccessDenied('Не задана настройка ya_pickup_ids', 'Не указаны точки самовывоза', 403);
}
define('YA_MARKET_API', $modx->getOption('ya_market_api'));
define('YA_API_KEY', $modx->getOption('ya_api_key'));
$delivObj = $modx->getObject('msDelivery', 2);
define('MIN_DELIVERY_PRICE', $delivObj->price?:'800');
define('DISTANCE_PRICE', $delivObj->distance_price?:'30');
define('PICKUP_IDS', $modx->getOption('ya_pickup_ids')?:'');
//OAuth
define('OAUTH_TOKEN', $modx->getOption('ya_oauth_token')?:'');
define('OAUTH_CLIENT_ID', $modx->getOption('ya_oauth_id')?:'');
//URL Я.Маркета
define('YA_URL', 'https://api.partner.market.yandex.ru/v2/');
define('YA_SHOP_ID', $modx->getOption('ya_shop_id')?:'');
//функ-ия коннекта к Я.Маркету
function httpRequestYa($url, $data, $method = 'GET'){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, YA_URL . 'campaigns/'.YA_SHOP_ID.'/' . $url . '.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Authorization: OAuth oauth_token="' . OAUTH_TOKEN . '", oauth_client_id="' . OAUTH_CLIENT_ID . '"'));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$returned = curl_exec($ch);
curl_close ($ch);
return $returned;
}
//функ-ия извещения о просроченном токене
function sendError401(){
global $modx;
$msg = '
Просрочен авторизационный токен для Я.Маркета. Перейдите по ссылке https://oauth.yandex.ru/authorize?response_type=token&client_id='.OAUTH_CLIENT_ID.' , чтобы получить новый. Нужно быть авторизованным в том аккаунте Яндекса, в котором подключен Я.Маркет для сайта. Если это не сделать, то вы не будете получать заказы с Я.Маркета
';
$emails = array_map('trim', explode(',', $modx->getOption('ms2_email_manager')));
$modx->getService('mail', 'mail.modPHPMailer');
$modx->mail->set(modMail::MAIL_BODY, $msg);
$modx->mail->set(modMail::MAIL_FROM, 'noreply@' . MODX_HTTP_HOST);
$modx->mail->set(modMail::MAIL_SENDER, 'noreply@' . MODX_HTTP_HOST);
$modx->mail->set(modMail::MAIL_SUBJECT, 'Срочно нужны действия на сайте ' . MODX_HTTP_HOST);
foreach($emails as $e){
$modx->mail->address('to', $e);
}
$modx->mail->setHTML(true);
if (!$modx->mail->send()) {
$modx->log(modX::LOG_LEVEL_ERROR,'An error occurred while trying to send the email: '.$modx->mail->mailer->ErrorInfo);
}
$modx->mail->reset();
return true;
}
//обработка методов
switch($action){
//смена статуса заказа
case 'changestatus':
$input = json_decode(file_get_contents('php://input'), true);
if($input['ya_order_id'] && $input['status']){
$statuses = [
3 => 'DELIVERY',
4 => 'CANCELLED',
5 => 'DELIVERED',
6 => 'CANCELLED',
7 => 'CANCELLED',
];
if(isset($statuses[$input['status']])){
$data['order'] = array(
'status' => $statuses[$input['status']]
);
if($statuses[$input['status']] == 'CANCELLED'){
$data['order']['substatus'] = 'USER_CHANGED_MIND';
}
if($statuses[$input['status']] == 'CANCELLED' && $input['status'] == 4){
$data['order']['substatus'] = 'SHOP_FAILED';
}
if($statuses[$input['status']] == 'CANCELLED' && $input['status'] == 7){
$data['order']['substatus'] = 'USER_UNREACHABLE';
}
$resp = httpRequestYa('orders/'.$input['ya_order_id'].'/status', $data, 'PUT');
//$modx->log(1, print_r($resp, true));
$resp = json_decode($resp, true);
if($resp['status'] == 'ERROR' && ($resp['error']['code'] == 401 || $resp['error']['code'] == 403)){
sendError401();
}
if($input['delivery_id'] == 1 && $statuses[$input['status']] == 'DELIVERY'){
sleep(5);
$data['order'] = array(
'status' => 'PICKUP'
);
$resp = httpRequestYa('orders/'.$input['ya_order_id'].'/status', $data, 'PUT');
$resp = json_decode($resp, true);
if($resp['status'] == 'ERROR' && $resp['error']['code'] == 401){
sendError401();
}
}
//$modx->log(1, print_r($resp, true));
}
}
//сброс сессий
@session_write_close();
exit;
break;
//устновка токена от Я.Маркета
case 'settoken':
header('Content-type: text/html; charset=utf-8');
$url = $_SERVER['REQUEST_URI'];
if($_POST['access_token']){
$o = $modx->getObject('modSystemSetting',array('key' =>'ya_oauth_token'));
if($o){
$o->set('value', $_POST['access_token']);
$o->save();
$modx->cacheManager->refresh();
die('Установлен токен: ' . $_POST['access_token']);
}
}
$out = '
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<div id="content"></div>
<script>
var access_token = new URL(window.location.href).hash.split(\'&\').filter(function(el) { if(el.match(\'access_token\') !== null) return true; })[0].split(\'=\')[1];
$.post(\''.$url.'\', {access_token: access_token}, function (response) {
$(\'#content\').text(response);
}, \'text\')
.fail(function () {
console.error(\'[settoken] Bad request.\');
})
.done(function () {
});
</script>
';
die($out);
break;
// метод отвечающий Маркету с уточнёнными данными по ценам товаров и ценам доставки
case 'cart':
//находим тело запроса в JSON
$input = json_decode(file_get_contents('php://input'),true);
if($method != 'POST') getAccessDenied();
/*$modx->log(1, print_r($input, true));
$modx->log(1, print_r(file_get_contents('php://input'), true));
$modx->log(1, print_r($_REQUEST, true));
$modx->log(1, print_r($_SERVER, true));*/
$out = $input?:['success' => false];
if(!isset($input['cart'])) getAccessDenied('Пустая секция cart', 'Пустая секция cart', 400);
$input['cart']['paymentMethods'] = array("YANDEX","CARD_ON_DELIVERY","CASH_ON_DELIVERY");
unset($input['cart']['currency']);
if($input['cart']['items']){
$address = $input['cart']['delivery'];
unset($input['cart']['delivery']);
$country = $address['region'];
while($country['type'] != 'COUNTRY'){
$country = $country['parent'];
}
$city = $address['region'];
while($city['type'] != 'CITY'){
$city = $city['parent']?:[];
if(!$city['id']){
break;
}
}
// если указан точный адрес
$addr = $address['address']?:[];
if(!$city['id']){
$city = $address['region'];
}
$pickups = array_map('trim', explode(',', PICKUP_IDS));
$pcs = [];
foreach($pickups as $pickup){
$pcs[] = ['code' => (string)$pickup];
}
$input['cart']['deliveryCurrency'] = 'RUR';
$input['cart']['deliveryOptions'][0] = [
'id' => '1',
'price' => 0,
'serviceName' => 'Самовывоз',
'type' => 'PICKUP',
'outlets' => $pcs,
'dates' => [
'fromDate' => (date('H') > 14)?date('d-m-Y', strtotime('+5 days', time())):date('d-m-Y', strtotime('+4 days', time())),
'toDate' => (date('H') > 14)?date('d-m-Y', strtotime('+7 days', time())):date('d-m-Y', strtotime('+6 days', time())),
/*'intervals' => [
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+5 days', time())):date('d-m-Y', strtotime('+4 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+6 days', time())):date('d-m-Y', strtotime('+5 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+7 days', time())):date('d-m-Y', strtotime('+6 days', time()))]
]*/
]
];
if($city['id'] == 213){ // если Москва
$input['cart']['deliveryOptions'][1] = [
'id' => '2',
'price' => (double)MIN_DELIVERY_PRICE,
'serviceName' => $delivObj->name,
'type' => 'DELIVERY',
'dates' => [
'fromDate' => (date('H') > 14)?date('d-m-Y', strtotime('+5 days', time())):date('d-m-Y', strtotime('+4 days', time())),
'toDate' => (date('H') > 14)?date('d-m-Y', strtotime('+6 days', time())):date('d-m-Y', strtotime('+5 days', time())),
'intervals' => [
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+5 days', time())):date('d-m-Y', strtotime('+4 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+6 days', time())):date('d-m-Y', strtotime('+5 days', time()))],
]
]
];
}
else{
$input['cart']['deliveryOptions'][1] = [
'id' => '2',
'price' => (double)MIN_DELIVERY_PRICE,
'serviceName' => $delivObj->name,
'type' => 'DELIVERY',
'dates' => [
'fromDate' => (date('H') > 14)?date('d-m-Y', strtotime('+5 days', time())):date('d-m-Y', strtotime('+4 days', time())),
'toDate' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time())),
'intervals' => [
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+5 days', time())):date('d-m-Y', strtotime('+4 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+6 days', time())):date('d-m-Y', strtotime('+5 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+7 days', time())):date('d-m-Y', strtotime('+6 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+8 days', time())):date('d-m-Y', strtotime('+7 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time()))],
]
]
];
// Обращение к http-геокодеру
if($xml = simplexml_load_file('https://geocode-maps.yandex.ru/1.x/?geocode='.urlencode($country['name'] . ', ' . $city['name']).'&results=1&apikey='.YA_API_KEY)){
// Если геокодировать удалось
$found = $xml->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found;
if ($found > 0) {
$coords = str_replace(' ', ',', $xml->GeoObjectCollection->featureMember->GeoObject->Point->pos);
$coords = explode(',', $coords);
$coords_lat = round($coords[1], 4); //меняем местами координаты из ответа Яндекса
$coords_long = round($coords[0], 4);
$coords[0] = $coords_lat;
$coords[1] = $coords_long;
//$coords = implode(',', $coords);
$distance = getDistance($coords[0],$coords[1],55.581622,37.709763);
if($distance > 30000){
if(isset($input['cart']['deliveryOptions'][1])){
$input['cart']['deliveryOptions'][1]['price'] = (double)number_format( round(MIN_DELIVERY_PRICE + ( ($distance - 30000) * DISTANCE_PRICE/1000 ), 2) , 2, '.', '');
if($distance > 300000){
$input['cart']['deliveryOptions'][1]['serviceName'] = 'Доставка ТК';
$input['cart']['deliveryOptions'][1]['price'] = (double)number_format( round(MIN_DELIVERY_PRICE + ( ($distance - 300000) * DISTANCE_PRICE/(($distance > 1000000)?40000:10000) ), 2) , 2, '.', '');
$input['cart']['deliveryOptions'][1]['dates'] = [
'fromDate' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time())),
'toDate' => (date('H') > 14)?date('d-m-Y', strtotime('+10 days', time())):date('d-m-Y', strtotime('+9 days', time())),
'intervals' => [
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+10 days', time())):date('d-m-Y', strtotime('+9 days', time()))],
]
];
}
}
}
}
}
}
// считаем по точному адресу, если он есть
if($addr['lat'] && $addr['lon'] && $city['id'] != 213){
$distance = getDistance($coords[0],$coords[1],55.581622,37.709763);
if($distance > 30000){
if(isset($input['cart']['deliveryOptions'][1])){
$input['cart']['deliveryOptions'][1]['price'] = (double)number_format( round(MIN_DELIVERY_PRICE + ( ($distance - 30000) * DISTANCE_PRICE/1000 ), 2) , 2, '.', '');
if($distance > 300000){
$input['cart']['deliveryOptions'][1]['serviceName'] = 'Доставка ТК';
$input['cart']['deliveryOptions'][1]['price'] = (double)number_format( round(MIN_DELIVERY_PRICE + ( ($distance - 300000) * DISTANCE_PRICE/(($distance > 1000000)?40000:10000) ), 2) , 2, '.', '');
$input['cart']['deliveryOptions'][1]['dates'] = [
'fromDate' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time())),
'toDate' => (date('H') > 14)?date('d-m-Y', strtotime('+10 days', time())):date('d-m-Y', strtotime('+9 days', time())),
'intervals' => [
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+10 days', time())):date('d-m-Y', strtotime('+9 days', time()))],
]
];
}
}
}
}
elseif($addr['country'] && $addr['city'] && $city['id'] != 213){
// Обращение к http-геокодеру
if($xml = simplexml_load_file('https://geocode-maps.yandex.ru/1.x/?geocode='.urlencode($addr['country'] . ', ' . $addr['city'] . ', ' . $addr['street'] . ' ' . $addr['house']).'&results=1&apikey='.YA_API_KEY)){
// Если геокодировать удалось
$found = $xml->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found;
if ($found > 0) {
$coords = str_replace(' ', ',', $xml->GeoObjectCollection->featureMember->GeoObject->Point->pos);
$coords = explode(',', $coords);
$coords_lat = round($coords[1], 4); //меняем местами координаты из ответа Яндекса
$coords_long = round($coords[0], 4);
$coords[0] = $coords_lat;
$coords[1] = $coords_long;
//$coords = implode(',', $coords);
$distance = getDistance($coords[0],$coords[1],55.581622,37.709763);
if($distance > 30000){
if(isset($input['cart']['deliveryOptions'][1])){
$input['cart']['deliveryOptions'][1]['price'] = (double)number_format( round(MIN_DELIVERY_PRICE + ( ($distance - 30000) * DISTANCE_PRICE/1000 ), 2) , 2, '.', '');
if($distance > 300000){
$input['cart']['deliveryOptions'][1]['serviceName'] = 'Доставка ТК';
$input['cart']['deliveryOptions'][1]['price'] = (double)number_format( round(MIN_DELIVERY_PRICE + ( ($distance - 300000) * DISTANCE_PRICE/(($distance > 1000000)?40000:10000) ), 2) , 2, '.', '');
$input['cart']['deliveryOptions'][1]['dates'] = [
'fromDate' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time())),
'toDate' => (date('H') > 14)?date('d-m-Y', strtotime('+10 days', time())):date('d-m-Y', strtotime('+9 days', time())),
'intervals' => [
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+9 days', time())):date('d-m-Y', strtotime('+8 days', time()))],
['date' => (date('H') > 14)?date('d-m-Y', strtotime('+10 days', time())):date('d-m-Y', strtotime('+9 days', time()))],
]
];
}
}
}
}
}
}
foreach($input['cart']['items'] as &$item){
$allowedKeys = array('offerId', 'price', 'feedId', 'count', 'delivery');
$item = array_intersect_key($item, array_flip($allowedKeys));
$is_available = false;
$offer = explode('MODIFY', $item['offerId']);
if($resource = $modx->getObject('msProduct', $offer[0])){
$sizes = json_decode($resource->getTVValue('sizes'), true);
foreach($sizes as $s){
if($country['id'] != 225){//если не Россия
$item['delivery'] = false;
}
if(!$resource->published || $resource->deleted){
$item['count'] = 0;
}
/*if($item['count'] == 99999){//для прохождения тестов Я.Маркета
$item['count'] = 0;
}*/
if($s['MIGX_id'] == $offer[1]){
$is_available = true;
$item['price'] = (double)number_format($s['old_price'], 2, '.', '');
if($item['count'] > 10){
$item['price'] = (double)number_format($s['price'], 2, '.', '');
}
}
}
if(!$is_available){
$item['count'] = 0;
}
}
else{
$item['count'] = 0;
}
}
}
else{
getAccessDenied('Нет товаров в заказе', 'Нет товаров в заказе', 400);
}
$out = $input?:$out;
//сброс сессий
@session_write_close();
echo json_encode($out);
exit;
break;
// ответ Маркету о статусе заказа, если он принимается сайтом
case 'order/accept':
//находим тело запроса в JSON
$input = json_decode(file_get_contents('php://input'),true);
if($method != 'POST') getAccessDenied();
/*$modx->log(1, print_r($input, true));
$modx->log(1, print_r(file_get_contents('php://input'), true));
$modx->log(1, print_r($_REQUEST, true));
$modx->log(1, print_r($_SERVER, true));*/
if(!isset($input['order'])) getAccessDenied('Пустая секция order', 'Пустая секция order', 400);
$out = $input['order']['id']?['order' => ['accepted' => true, 'id' => (string)$input['order']['id']]]:['order' => ['accepted' => false, 'reason' => 'OUT_OF_DATE']];
//сброс сессий
@session_write_close();
echo json_encode($out);
exit;
break;
// метод создания заказа в системе
case 'order/status':
//находим тело запроса в JSON
$input = json_decode(file_get_contents('php://input'),true);
if($method != 'POST') getAccessDenied();
/*$modx->log(1, print_r($input, true));
$modx->log(1, print_r(file_get_contents('php://input'), true));
$modx->log(1, print_r($_REQUEST, true));
$modx->log(1, print_r($_SERVER, true));*/
if(!isset($input['order'])) getAccessDenied('Пустая секция order', 'Пустая секция order', 400);
$scriptProperties = array(
'json_response' => true,
'max_count' => $modx->getOption('ms2_cart_max_count')?:100000000000000000000000000,
);
$miniShop2 = $modx->getService('minishop2','miniShop2', MODX_CORE_PATH . 'components/minishop2/model/minishop2/', $scriptProperties);
if (!($miniShop2 instanceof miniShop2)) getAccessDenied('Класс магазина не загружен','Класс магазина не загружен',500);
$miniShop2->initialize($modx->context->key, $scriptProperties);
$miniShop2->cart->clean();
$miniShop2->order->clean();
switch($input['order']['status']){
case 'PROCESSING':
$miniShop2->order->add('order_id', $input['order']['id']);
$miniShop2->order->add('delivery_cost', $input['order']['delivery']['price']);
$miniShop2->order->add('delivery', $input['order']['delivery']['id']);
$miniShop2->order->add('payment', $input['order']['paymentType'] == 'PREPAID' ? 3 : 1);
//$miniShop2->order->add('email', '');
$miniShop2->order->add('phone', $input['order']['buyer']['phone']);
$miniShop2->order->add('receiver', $input['order']['buyer']['firstName'] . ' ' . $input['order']['buyer']['middleName'] . ' ' . $input['order']['buyer']['lastName']);
$miniShop2->order->add('street', $input['order']['delivery']['address']?implode(', ', $input['order']['delivery']['address']):'');
$miniShop2->order->add('address', $input['order']['delivery']['address']?implode(', ', $input['order']['delivery']['address']):'');
$notes = '';
if(isset($input['order']['delivery']['dates']['fromDate'])){
$notes .= "Желаемая дата доставки: {$input['order']['delivery']['dates']['fromDate']} - {$input['order']['delivery']['dates']['toDate']}. ";
}
$notes .= $input['order']['notes']?:'';
$miniShop2->order->add('comment', $notes);
foreach($input['order']['items'] as &$item){
$offer = explode('MODIFY', $item['offerId']);
if($resource = $modx->getObject('msProduct', $offer[0])){
$sizes = json_decode($resource->getTVValue('sizes'), true);
foreach($sizes as $s){
if($s['MIGX_id'] == $offer[1]){
$miniShop2->cart->add($offer[0], $item['count'], array('size' => $s['size'], 'color' => $s['color'], 'factura' => $s['factura']));
}
}
}
}
//установка цен покупаемых товаров из JSON массива от Яшки
if($cart_array = $miniShop2->cart->get()){
foreach($input['order']['items'] as &$item){
$offer = explode('MODIFY', $item['offerId']);
foreach($cart_array as &$cart_item){
if($cart_item['id'] == $offer[0]){
$cart_item['price'] = $item['price'];
}
}
}
$miniShop2->cart->set($cart_array);
}
$properties = $miniShop2->order->get('properties');
if(empty($properties)){
$properties = array();
}
else{
if(is_array($properties)){
$properties = $properties;
}
elseif (!is_array(json_decode($properties, true))) {
$properties = array();
}
else{
$properties = json_decode($properties, true);
}
}
$properties['paymentType'] = $input['order']['paymentType'];
$properties['substatus'] = $input['order']['substatus'];
$miniShop2->order->add('properties', json_encode($properties));
$response = $miniShop2->order->submit();
$response = json_decode($response, true);
if(!$response['success']){
$modx->log(1, print_r($response, true));
getAccessDenied($response['data']?implode(', ', $response['data']):$response['message'], $response['message'], 400);
}
break;
case 'CANCELLED':
$msg = '';
switch($input['order']['substatus']){
case 'USER_BOUGHT_CHEAPER':
$msg = 'Причина отмены Покупателем: Покупатель нашёл дешевле';
break;
case 'USER_NOT_PAID':
$msg = 'Причина отмены Маркетом: Покупатель не оплатил заказ в отведённое время';
break;
case 'USER_CHANGED_MIND':
$msg = 'Причина отмены Покупателем: Покупатель передумал';
break;
}
$status_id = 6;
$ms_order = $modx->getObject('msOrder', array('ya_order_id' => $input['order']['id']));
if($ms_order){
$ms_order->set('comment', $msg);
$ms_order->save();
$miniShop2->changeOrderStatus($ms_order->id, $status_id);
}
break;
}
//сброс сессий
@session_write_close();
exit;
break;
//TODO: https://yandex.ru/dev/market/partner-dsbs/doc/dg/reference/post-order-cancellation-notify.html
case 'order/cancellation/notify':
getAccessDenied('метод в разработке', 'метод в разработке', 404);
break;
}
$modx->sendUnauthorizedPage();
getAccessDenied();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment