Last active
July 24, 2023 11:30
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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