<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
die();
$raw_data = file_get_contents("php://input");
//кастомная функция логирования, для отладки
payQrLogToFile($raw_data);
$event = json_decode($raw_data);
$secretKeyIn = $arParams['SECRET_KEY_IN']; // Входящий ключ SecretKeyIn этого «Магазина», указанный в личном кабинете
$secretKeyOut = $arParams['SECRET_KEY_OUT']; // Исходящий ключ SecretKeyOut этого «Магазина», указанный в личном кабинете
header("PQRSecretKey:" . $secretKeyOut); // Подписать ответ исходящим ключом для подтверждения, что ответ действительно от «Магазина»
if ($event->type == "invoice.order.creating" && CModule::IncludeModule("iblock") && CModule::IncludeModule("sale") && CModule::IncludeModule("catalog")) /* Проверяем тип события на соответствие типу события для создания заказа и задействуем нужные компоненты*/ {
$invoice = $event->data; // Объект «Счет на оплату» (invoice)
$orderGroupParts = explode(".", $invoice->orderGroup);
/* Получаем пришедшие идентификаторы учетной системы ИД сайта ИД пользователя на сайте и ИД пользователя в учетной системе (это редкая особенность «1С-Битрикс», часто в учетных системах понятия ИД сайта и ИД пользователя отсутствуют, а в формировании участвуют только артикулы позиций в заказе) */
$siteId = $orderGroupParts[0]; // ИД сайта (был сохранен на уровне кнопки PayQR в data-orderGroup первым параметром)
$fuserId = $orderGroupParts[1]; // ИД пользователя на сайте (был сохранен на уровне кнопки PayQR в data-orderGroup вторым параметром)
$userId = $orderGroupParts[2]; // ИД пользователя в учетной системе (был сохранен на уровне кнопки PayQR в data-orderGroup третьим параметром)
if (empty($userId))
$userId = $arParams['DEFAULT_USER_ID'];
$arFieldsOrder = array();
$arFieldsOrder[$arParams['FIELD_FIRSTNAME_ID']] .= ', ' . $invoice->customer->firstName;
$arFieldsOrder[$arParams['FIELD_LASTNAME_ID']] .= ', ' . $invoice->customer->lastName;
$arFieldsOrder[$arParams['FIELD_PHONE_ID']] .= ', ' . $invoice->customer->phone;
$arFieldsOrder[$arParams['FIELD_EMAIL_ID']] .= ', ' . $invoice->customer->email;
$arFieldsOrder[$arParams['FIELD_COUNTRY_ID']] .= ', ' . $invoice->delivery->country;
$arFieldsOrder[$arParams['FIELD_CITY_ID']] .= ', ' . $invoice->delivery->city;
$arFieldsOrder[$arParams['FIELD_ZIP_ID']] .= ', ' . $invoice->delivery->zip;
if ($arParams['FIELD_ADDRESS_ID'] > 0):
$arFieldsOrder[$arParams['FIELD_ADDRESS_ID']] .= ', ';
if (!empty($invoice->delivery->street))
$arAddress[] = 'ул. ' . $invoice->delivery->street;
if (!empty($invoice->delivery->house))
$arAddress[] = 'д. ' . $invoice->delivery->house;
if (!empty($invoice->delivery->unit))
$arAddress[] = 'корп.. ' . $invoice->delivery->unit;
if (!empty($invoice->delivery->building))
$arAddress[] = 'стр. ' . $invoice->delivery->building;
if (!empty($invoice->delivery->flat))
$arAddress[] = 'кв. ' . $invoice->delivery->flat;
if (!empty($invoice->delivery->hallway))
$arAddress[] = 'подъезд ' . $invoice->delivery->hallway;
if (!empty($invoice->delivery->floor))
$arAddress[] = 'этаж ' . $invoice->delivery->floor;
if (!empty($invoice->delivery->intercom))
$arAddress[] = 'домофон ' . $invoice->delivery->intercom;
$arFieldsOrder[$arParams['FIELD_ADDRESS_ID']] .= implode(', ', $arAddress);
endif;
//$arFieldsOrder[$arParams['FIELD_PAYQR_ID']] = $invoice->payqrNumber;
$commentOrder = $invoice->delivery->comment;
AddMessage2Log('FUSERID: ' . $fuserId . ' | USERID: ' . $userId . ' | ');
$dbBasketItems = CSaleBasket::GetList( // Получаем корзину этого пользователя из интернет-сайта
array(
"NAME" => "ASC",
"ID" => "ASC"
), array(
"FUSER_ID" => $fuserId,
"LID" => SITE_ID,
"ORDER_ID" => "NULL"
), false, false, array(
"ID",
"PRODUCT_ID",
"PRODUCT_PRICE_ID",
"NAME",
"QUANTITY",
"CAN_BUY",
"PRICE"
));
$arBasketItems = array();
while ($arBasketItem = $dbBasketItems->Fetch()) /* На всякий случай, приводим состояние корзины на интернет-сайте в соответствие с содержанием заказа в PayQR (заказ, который начал оформляться в PayQR, приоритетнее) */
$arBasketItems[] = $arBasketItem;
$removingPositionKeys = array();
/* Массив удаляемых из корзины PayQR элементов, которые не удалось поместить в корзину магазина (нет такого товара или не удалось добавить к корзину) */
$invoice->amount = 0; // Очищаем итоговую сумму счета для пересчета по текущим ценам интернет-сайта, так как они могли измениться
payQrLogToFile("\\narBasketItems: " . var_export($arBasketItems, true));
payQrLogToFile("\\ninvoice->cart: " . var_export($invoice->cart, true));
foreach ($invoice->cart as $positionKey => $position) // Проверяем корзину PayQR и обновляем корзину магазина
{
$arPrice = CPrice::GetByID(intval($position->article));
$arDiscounts = CCatalogDiscount::GetDiscountByPrice($arPrice["ID"], $USER->GetUserGroupArray(), "N", SITE_ID);
$discountPrice = CCatalogProduct::CountPriceWithDiscount($arPrice["PRICE"], $arPrice["CURRENCY"], $arDiscounts);
$arPrice["DISCOUNT_PRICE"] = $discountPrice;
payQrLogToFile("\\narPrice: " . var_export($arPrice, true));
if ($arProduct = CIBlockElement::GetByID(intval($arPrice["PRODUCT_ID"]))->Fetch()) {
$position->amount = $arPrice["DISCOUNT_PRICE"] * $position->quantity; // Актуализируем сумму по позиции
$position->name = $arProduct["NAME"]; // Актуализируем название позиции
$removingIndex = -1;
foreach ($arBasketItems as $index => $arBasketItem) /* Проверяем текущую корзину на интернет-сайте на соответствие заказу в приложении */
if ($arBasketItem["PRODUCT_PRICE_ID"] == $position->article) {
if ($arBasketItem["QUANTITY"] != $position->quantity) // Проверяем совпадение количества
CSaleBasket::Update($arBasketItem["ID"], array(
"QUANTITY" => $position->quantity
));
/* Приводим в соответствие с тем, что в приложении, если есть расхождения */
$removingIndex = $index;
break;
}
if ($removingIndex >= 0)
unset($arBasketItems[$removingIndex]);
/* Удаляем элементы из списка, которые успешно обработали, за ненадобностью */
else if (!CSaleBasket::Add(array(
/* Заполняем корзину в учетной системе для создания заказа (это редкая особенность «1С-Битрикс», часто в учетных системах можно сразу создать заказ, а потом заполнить его содержимое, без необходимости эмуляции предварительного создания корзины) */
"PRODUCT_ID" => $arPrice["PRODUCT_ID"],
"PRODUCT_PRICE_ID" => $arPrice["ID"],
"PRICE" => $arPrice["PRICE"],
"CURRENCY" => $arParams['CURRENCY'],
"QUANTITY" => $position->quantity,
"LID" => $siteId,
"FUSER_ID" => $fuserId,
"DELAY" => "N",
"CAN_BUY" => "Y",
"NAME" => $arProduct["NAME"],
"CALLBACK_FUNC" => "",
"MODULE" => "sale",
"NOTES" => "",
"ORDER_CALLBACK_FUNC" => "",
"DETAIL_PAGE_URL" => "",
"CANCEL_CALLBACK_FUNC" => "",
"PAY_CALLBACK_FUNC" => ""
)))
$removingPositionKeys[] = $positionKey;
/* Удаляем позицию из заказа в приложении, если учетная система отказала в добавлении этой позиции в корзину по любым причинам */
$invoice->amount += $position->amount; // Пересчитываем итоговую сумму заказа на основе данных учетной системы
} else
$removingPositionKeys[] = $positionKey;
/* Удаляем позицию из заказа в приложении, если указанный товар не был найден в учетной системе (например, закончился на складе) */
}
foreach ($arBasketItems as $arBasketItem) /* Удаляем из корзины на интернет-сайте те товары, которые отсутствуют в заказе в приложении PayQR */
CSaleBasket::Delete($arBasketItem["ID"]);
foreach ($removingPositionKeys as $positionKey) /* Удаляем из корзины на интернет-сайте те товары, которые отсутствуют в учетной системе интернет-сайта */
unset($invoice->cart[$positionKey]);
payQrLogToFile("\\narBasketItems: " . var_export($arBasketItems, true));
payQrLogToFile("\\ninvoice->amount: " . var_export($invoice->amount, true));
$dbBasketItems = CSaleBasket::GetList( // Получаем корзину этого пользователя из интернет-сайта
array(
"NAME" => "ASC",
"ID" => "ASC"
), array(
"FUSER_ID" => $fuserId,
"LID" => SITE_ID,
"ORDER_ID" => "NULL"
), false, false, array(
"ID",
"PRODUCT_ID",
"PRODUCT_PRICE_ID",
"NAME",
"QUANTITY",
"CAN_BUY",
"PRICE"
));
$arBasketItems = array();
while ($arBasketItem = $dbBasketItems->Fetch()) /* На всякий случай, приводим состояние корзины на интернет-сайте в соответствие с содержанием заказа в PayQR (заказ, который начал оформляться в PayQR, приоритетнее) */
$arBasketItems[] = $arBasketItem;
payQrLogToFile("\\narBasketItems: " . var_export($arBasketItems, true));
//exit;
if (count($invoice->cart) > 0) /* Создаем заказ в учетной системе интернет-сайта, если оформляемая корзина после всех проверок осталась непустой, иначе не создаем заказ */ {
$invoice->orderId = CSaleOrder::Add(array( // Добавляем заказ в учетную систему
"LID" => $siteId,
"PERSON_TYPE_ID" => 1,
"PAYED" => "N",
"CANCELED" => "N",
"STATUS_ID" => "N",
"PRICE" => $invoice->amount,
"CURRENCY" => $arParams['CURRENCY'],
"USER_ID" => intval($userId),
"USER_DESCRIPTION" => $commentOrder
));
if ($invoice->orderId == false)
AddMessage2Log('Ошибка добавления заказа');
if (count($arFieldsOrder) > 0) {
foreach ($arFieldsOrder as $id => $value) {
$value = substr($value, 2);
if ($id > 0 && !empty($value) && $arOrderProps = CSaleOrderProps::GetByID($id)) {
CSaleOrderPropsValue::Add(array(
"ORDER_ID" => $invoice->orderId,
"ORDER_PROPS_ID" => $id,
"NAME" => $arOrderProps['NAME'],
"CODE" => $arOrderProps['CODE'],
"VALUE" => $value
));
}
}
}
CSaleBasket::OrderBasket($invoice->orderId, $fuserId, $siteId);
/* Связываем только что созданный заказ с текущей корзиной на интернет-сайте, чтобы корзина на интернет-сайте не осталась «брошенной» */
}
//------- Формирование заказа завершено в 1C-Битрикс -------
$raw_data = json_encode($event);
payQrLogToFile($raw_data);
echo $raw_data;
} else if ($event->type == "invoice.paid" && CModule::IncludeModule("sale")) /* Проверяем тип события на соответствие типу события для оплаты заказа и задействуем нужные компоненты этой учетной системы */ {
/* логика оплаты заказа */
} else
echo json_encode(array(
"id" => $event->id
));
?>