связка ishop и программа Покупка на Яндекс-маркете

+11
1.96K
Яндекс маркет позволяет заказывать товары непосредственно с яндекса — удобная штука. Мое решение позволяет использовать эту возможность для instant Shop.

описание программы: help.yandex.ru/partnermarket/purchase/about.xml
описание API: api.yandex.ru/market/partner/doc/dg/reference/purchase-methods.xml


1. в таблице cms_shop_orders добавляем поле market_id int(11) — в этом поле будет хоанится айди заказа с маркета
2. Параметры такие:
в аутентификации oauth.yandex.ru/ указываем помимо прочего:

Ссылка на приложение: site.ru (ну ессесн свой сайт укажите 😊)
Callback URI: site.ru/shop/tokens


в маркете:

настройка API покупки

URL API: site.ru/shop/market
Авторизационный токен 63.......
Тип авторизации HEADER

Формат данных JSON




3. файл router.php для шопа

  1.  
  2. <?php
  3.  
  4. function routes_shop(){
  5.  
  6. //YANDEX MARKET
  7. $routes[] = array(
  8. '_uri' => '/^shop\/tokens$/i',
  9. 'do' => 'tokens'
  10. );
  11. $routes[] = array(
  12. '_uri' => '/^shop\/market$/i',
  13. 'do' => 'market'
  14. );
  15. $routes[] = array(
  16. '_uri' => '/^shop\/market\/cart$/i',
  17. 'do' => 'market_cart'
  18. );
  19. $routes[] = array(
  20. '_uri' => '/^shop\/market\/order\/accept$/i',
  21. 'do' => 'market_order_accept'
  22. );
  23. $routes[] = array(
  24. '_uri' => '/^shop\/market\/order\/status$/i',
  25. 'do' => 'market_order_status'
  26. );
  27.  
  28. ....
  29. ....
  30.  


файл frontend.php

  1.  
  2. ...
  3. $menutitle = $inCore->menuTitle();
  4.  
  5. $auth_token = '63......'; //токен авторизации с яндекс-маркета
  6. ...
  7.  
  8. //Подключаем CSS к странице
  9. $inPage->addHeadCSS('templates/'.$_CFG['template'].'/css/inshop.css');
  10.  
  11.  
  12.  
  13. //============================================================================//
  14. //============================================================================//
  15.  
  16. //
  17. // YANDEX MARKET
  18. //
  19.  
  20. if ($do=='tokens'){
  21. //получение токена от яндекс OATH
  22. $token = $inCore->request2var('access_token', 'str');
  23.  
  24. if(!$token){
  25. echo 'идет перенаправление'; //через джава скрипт!! (код - в jquery.main.js)
  26. } else {
  27. $_SESSION['token'] = $token;
  28. $state = $inCore->request2var('state', 'int'); //через этот параметр мы передавали ID заказа
  29. $inCore->redirect('/admin/index.php?view=components&do=config&id=26&opt=set_y_status&order_id='.$state); //обратно в админку в раздел смена статуса маркета (но уже с токеном)
  30. }
  31. }
  32.  
  33. if ($do=='market_cart'){
  34.  
  35. $header = getallheaders();
  36. //проверяем токен
  37. if($header['Authorization']!=$auth_token){
  38. //неверный токен
  39. header("HTTP/1.0 403 Forbidden");
  40. die;
  41. }
  42.  
  43. $postdata = file_get_contents("php://input");
  44.  
  45. //в постдате переданы параметры о товарах в джсон формате
  46. $data = json_decode($postdata, 1);
  47.  
  48.  
  49. //возвращаем товары в яндекс
  50. $out = array();
  51. $out_items = array();
  52. foreach($data['cart']['items'] as $in_item) {
  53. $item = $inDB->get_fields('cms_shop_items', 'id='.$in_item['offerId'], 'price');
  54. $out_item['feedId'] = $in_item['feedId'];
  55. $out_item['offerId'] = $in_item['offerId'];
  56. $out_item['price'] = round($item['price']);
  57. $out_item['count'] = $in_item['count'];
  58. $out_item['delivery'] = true;
  59.  
  60. $out_items[] = $out_item;
  61. }
  62.  
  63. $out['cart']['items'] = $out_items; //товары
  64.  
  65. //доставка
  66. $out['cart']['deliveryOptions'][0]['type'] = 'DELIVERY';
  67. $out['cart']['deliveryOptions'][0]['serviceName'] = iconv('cp1251', 'utf-8', 'Наш курьер');
  68. $out['cart']['deliveryOptions'][0]['price'] = 0;
  69. $out['cart']['deliveryOptions'][0]['type'] = 'DELIVERY';
  70. $out['cart']['deliveryOptions'][0]['dates']['fromDate'] = date('d-m-Y');
  71.  
  72. //методы оплаты
  73. $out['cart']['paymentMethods'] = array('CASH_ON_DELIVERY');
  74.  
  75. $output_string = json_encode($out);
  76.  
  77. header('Content-Type: application/json;charset=utf-8');
  78. print $output_string;
  79.  
  80. die;
  81. }
  82.  
  83. if ($do=='market_order_accept'){
  84.  
  85. $header = getallheaders();
  86. //проверяем токен
  87. if($header['Authorization']!=$auth_token){
  88. //неверный токен
  89. header("HTTP/1.0 403 Forbidden");
  90. die;
  91. }
  92.  
  93.  
  94. $postdata = file_get_contents("php://input");
  95.  
  96. //в постдате переданы параметры о заказе в джсон формате
  97. $data = json_decode($postdata, 1);
  98.  
  99.  
  100. //оформляем заказ ПОКА БЕЗ ДАННЫХ О ЮЗЕРЕ! (их яндекс для данного события не передает, передает потом при смене статуса заказа)
  101. $customer_type = 'fis';
  102. $d_type = 5; //это ID Курьерская служба
  103.  
  104. $order['customer_name'] = 'Предварительный заказ с маркета';
  105. $order['customer_org'] = '';
  106. $order['customer_inn'] = '';
  107. $order['customer_phone'] = '';
  108. $order['customer_email'] = '';
  109. $order['customer_address'] = iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['country'].', '.$data['order']['delivery']['address']['city'].', '.$data['order']['delivery']['address']['street'].' '.$data['order']['delivery']['address']['house']);
  110. $order['customer_comment'] = '';
  111.  
//сохраняем товары в нужном формате
$items = array();
foreach($data['order']['items'] as $in_item) {
$item = $inDB->get_fields('cms_shop_items', 'id='.$in_item['offerId'], 'title, price, art_no, seolink, qty, id');
$out_item['title'] = $item['title'];
$out_item['price'] = $item['price'];
$out_item['art_no'] = $item['art_no'];
$out_item['seolink'] = $item['seolink'];
$out_item['qty'] = $item['qty'];
$out_item['cart_qty'] = $in_item['count'];
$out_item['item_id'] = $item['id'];
$out_item['is_deleted'] = 0;
$out_item['cart_id'] = 0;
$out_item['is_digital'] = 0;
$out_item['filename_item'] = '';
$out_item['filename_orig'] = '';
$out_item['filename'] = '';
$out_item['totalprice'] = $item['price']*$item['cart_qty'];
$items[] = $out_item;
}
$order['items'] = $inCore->arrayToYaml($items);
$order['giftcode'] = '';
$order['market_id'] = $data['order']['id']; //это ID заказа в яндекс-маркете
$order['status'] = 0;
$order['user_id'] = 0;
$order['summ'] = $model->calculateOrderSumm($items, $d_type, '');

if ($d_type){
$delivery_types = $model->getDeliveryTypes($order['summ']);
$order['d_type'] = $d_type;
$order['d_price'] = $delivery_types[$d_type]['price'];
} else {
$order['d_type'] = $d_type;
$order['d_price'] = 0;
}

//удаляем старые заказы для этой сессии
$model->deleteExpiredOrders(session_id());

$order['description'] = 'Предварительный заказ с маркета';

//сохраняем новый заказ
$order['id'] = $model->addOrder($order);

$out['order']['id'] = $order['id'];
$out['order']['accepted'] = true;
$output_string = json_encode($out);

header('Content-Type: application/json;charset=utf-8');
print $output_string;

die;

}

if ($do=='market_order_status'){

$header = getallheaders();
//проверяем токен
if($header['Authorization']!=$auth_token){
//неверный токен
header("HTTP/1.0 403 Forbidden");
die;
}

$postdata = file_get_contents("php://input");

//в постдате переданы параметры о заказе в джсон формате
$data = json_decode($postdata, 1);

$order = $inDB->get_fields('cms_shop_orders', 'market_id='.$data['order']['id'], 'id');

$status = 1;
if($data['order']['status']=='PROCESSING') $status = 1;
if($data['order']['status']=='DELIVERY') $status = 4;
if($data['order']['status']=='DELIVERED') $status = 2;
if($data['order']['status']=='CANCELLED') $status = 5;

//обрабатываем комментарий, полный адрес и ФИО покупателя
//преобразуем в кодировку сначала
$customer_comment = iconv('utf-8', 'cp1251', $data['order']['notes']);

$address = "Страна: ".iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['country']).", ";
$address.= "индекс: ".iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['postcode']).", ";
$address.= "город: ".iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['city']).", ";
$address.= "метро: ".iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['subway']).", ";
$address.= "улица: ".iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['street']).", ";
$address.= "дом: {$data['order']['delivery']['address']['house']}, ";
$address.= "корпус: {$data['order']['delivery']['address']['block']}, ";
$address.= "подъезд: {$data['order']['delivery']['address']['entrance']}, ";
$address.= "код домофона: {$data['order']['delivery']['address']['entryphone']}, ";
$address.= "этаж: {$data['order']['delivery']['address']['floor']}, ";
$address.= "номер квартиры: {$data['order']['delivery']['address']['apartment']}, ";
$address.= "ФИО получателя заказа: ".iconv('utf-8', 'cp1251', $data['order']['delivery']['address']['recipient']).", ";
$address.= "тел получателя: {$data['order']['delivery']['address']['phone']}";
$inDB->query("UPDATE cms_shop_orders SET customer_address='{$address}' WHERE id={$order['id']}");

$customer_name = iconv('utf-8', 'cp1251', $data['order']['buyer']['lastName'].' '.$data['order']['buyer']['firstName'])." (заказ с маркета)";
$customer_phone = $data['order']['buyer']['phone'];
$customer_email = $data['order']['buyer']['email'];
$inDB->query("UPDATE cms_shop_orders SET customer_name='{$customer_name}', customer_phone='{$customer_phone}', customer_email='{$customer_email}' WHERE id={$order['id']}");

$inDB->query("UPDATE cms_shop_orders SET status={$status} WHERE id={$order['id']}");
$lttr = "Смена статуса заказа с яндекс маркета. №заказа внутренний №{$order['id']}, №заказа в маркете №{$data['order']['id']}. Новый статус заказа: {$data['order']['status']}";
mail('vicoder@mail.ru', 'смена статуса на сезоте', $lttr); //на почту передается о смене статуса


die;

}



смена о статусе заказа приходит на мыло (например, юзер может ваще отменить заказ)


небольшая правка в функции:

public function addOrder($order){

$item = cmsCore::callEvent('ADD_SHOP_ORDER', $order);

$sql = "INSERT INTO cms_shop_orders (secret_key, date_created, date_payment, date_closed,
customer_name, customer_org, customer_phone, customer_email,
customer_address, customer_comment, customer_inn, items, d_type, d_price,
giftcode, status, summ, user_id, market_id)
VALUES ('{$order['secret_key']}', NOW(), NULL, NULL,
'{$order['customer_name']}', '{$order['customer_org']}', '{$order['customer_phone']}', '{$order['customer_email']}',
'{$order['customer_address']}', '{$order['customer_comment']}', '{$order['customer_inn']}', '{$order['items']}', '{$order['d_type']}', '{$order['d_price']}',
'{$order['giftcode']}', '{$order['status']}', '{$order['summ']}', '{$order['user_id']}', '{$order['market_id']}')";

$this->inDB->query($sql);

$order_id = $this->inDB->get_last_id('cms_shop_orders');

return $order_id;

}



4. В джава скрипте на самом сайте делаем пернаправление (это нужно для аутентификации приложения в яндексе):

$(document).ready(function(){
if (window.location.hash != ""){
window.location.href = "site.ru/shop/tokens?"+window.location.hash.replace(new RegExp("#","g"),"");
}
.....


5. изменеия в файле orders.tpl.php (выводим сообщения, если заказ — с маркета):


...
<?php foreach($items as $num=>$item){ ?>
<tr id="<?php echo $item['id']; ?>" class="item_tr">
<td><?php echo $item['id']; ?></td>
<td>
<div>
<a style="font-weight:bold;font-size:14px;" href="?view=components&do=config&id=<?php echo $component_id; ?>&opt=edit_order&item_id=<?php echo $item['id']; ?>"><?php echo $item['customer_name']; ?></a>
<?if($item['market_id']){?>Номер заказа на Я.Маркете = <?=$item['market_id']?><?}?>
</div>
...
<td><img src="/components/shop/images/status/<?php echo $item['status']; ?>.gif" />
<?if($item['market_id']){?>
<a href="<?=$component_uri?>&opt=set_y_status&order_id=<?=$item['id']?>">Сменить статус в y.market</a><?}?>
</td>
+5
AtlantisWeb AtlantisWeb 10 лет назад #
Очень не презентабельно, сделайте лучше мануал в текстовом формате и аттачем прикрепите к блогу.
А то какаято валка кода, даже под спойлер не убраноне говоря уже про обрамление в
Код PHP:
  1. кэг

Еще от автора

связка ishop и программа Покупка на Яндекс-маркете (2)
продолжение http://instantcms.ru/blogs/uluchshenija/svjazka-ishop-i-programa-pokupka-na-jandeks-markete.htmlпервой части
Сортировка дополнительных картинок в шопе drag'n'drop
Сделал возможность перемещения дополнительных картинок в шопе: т.е. можно мышкой взять и перетащить картинку вверх-вниз, как требуется
Глючек при попытке перенести статью из раздела в другой раздел
Обнаружился глючек при переносе статьи из раздела в раздел в функции moveArticlesToCat. У переносимой статьи не обновлялось seolink.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.