Последние темы


Shopkeeper3 и модуль оплаты PayAnyWay

  • Доброго времени суток! Модуль PayAnyWay, который я установил для онлайн-оплаты заказов, непосредственно после успешной оплаты меняет статус заказа на "Оплата получена", но письмо с смене статуса заказа покупателю не приходит. Если менять статус заказа вручную, письмо приходит.
    Похожая проблема с плагином "shk_updateInventory", если менять статус заказ вручную, количество товара уменьшается, а после изменения статуса через PayAnyWay этого не происходит.
    Их поддержка предполагает, что дело в Shopkeeper3. В чем может быть дело? Заранее благодарен за ответ.

    Код файла payanyway.inc.php, который отвечает за работу модуля

    <?php
    
    
    const paw_kassa_VAT0     = 1104;  // НДС 0%
    const paw_kassa_VAT10    = 1103;  // НДС 10%
    const paw_kassa_VAT18    = 1102;  // НДС 18%
    const paw_kassa_VATNOVAT = 1105;  // НДС не облагается
    const paw_kassa_VATWR10  = 1107;  // НДС с рассч. ставкой 10%
    const paw_kassa_VATWR18  = 1106;  // НДС с рассч. ставкой 18%
    
    function monetaPayURLResponse($mnt_id, $mnt_transaction_id, $mnt_data_integrity_code, $success = false,
    							  $repeatRequest = false, $echo = true, $die = true, $kassa_inventory = null,
    							  $kassa_customer = null, $kassa_delivery = null)
    {
    	if ($success === true)
    		$resultCode = '200';
    	elseif ($repeatRequest === true)
    		$resultCode = '402';
    	else
    		$resultCode = '500';
    	$mnt_signature = md5($resultCode.$mnt_id.$mnt_transaction_id.$mnt_data_integrity_code);
    	$response = '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
    	$response .= "<MNT_RESPONSE>\n";
    	$response .= "<MNT_ID>{$mnt_id}</MNT_ID>\n";
    	$response .= "<MNT_TRANSACTION_ID>{$mnt_transaction_id}</MNT_TRANSACTION_ID>\n";
    	$response .= "<MNT_RESULT_CODE>{$resultCode}</MNT_RESULT_CODE>\n";
    	$response .= "<MNT_SIGNATURE>{$mnt_signature}</MNT_SIGNATURE>\n";
    	if (!empty($kassa_inventory) || !empty($kassa_customer) || !empty($kassa_delivery))
    	{
    		$response .= "<MNT_ATTRIBUTES>\n";
    		foreach (array('INVENTORY' => $kassa_inventory, 'CUSTOMER' => $kassa_customer, 'DELIVERY' => $kassa_delivery) as $k => $v)
    			if (!empty($v))
    				$response .= "<ATTRIBUTE><KEY>{$k}</KEY><VALUE>{$v}</VALUE></ATTRIBUTE>\n";
    		$response .= "</MNT_ATTRIBUTES>\n";
    	}
    	$response .= "</MNT_RESPONSE>\n";
    	if ($echo === true)
    	{
    		header("Content-type: application/xml");
    		echo $response;
    	}
    	else
    		return $response;
    	if ($die === true)
    		die;
    	return '';
    }
    
    
    $modelpath = $modx->getOption('core_path') . 'components/shopkeeper3/model/';
    $modx->addPackage( 'shopkeeper3', $modelpath );
    
    if (isset($_REQUEST['payment']) && $_REQUEST['payment'] == 'payanyway') {
    	$payment_form = $modx->getOption('PAYMENT_FORM', $scriptProperties, null);
    	$modx->sendRedirect($payment_form);
    }
    
    if (isset($scriptProperties['action'])) {
    	switch ($scriptProperties['action']) {
    		case 'fail':
    			$order_id = (isset($_REQUEST['MNT_TRANSACTION_ID'])) ? $_REQUEST['MNT_TRANSACTION_ID'] : null;
    			if (is_null($order_id)) {
    				if (isset($_SESSION['shk_order_id'])) {
    					$order_id = $_SESSION['shk_order_id'];
    				}
    				else {
    					$order_id = $_SESSION['shk_lastOrder']['id'];
    				}
    			}
    
    			$order = $modx->getObject('shk_order', $order_id);
    			if (!$order) {
    				die('no shk_order object found');
    			}
    
    			$order->set('status', 5);
    			$order->save();
    
    			return '';
    			break;
    		case 'success':
    			break;
    		case 'callback':
    
    			if (!isset($_REQUEST['MNT_TRANSACTION_ID']))
    				monetaPayURLResponse($_REQUEST['MNT_ID'], $_REQUEST['MNT_TRANSACTION_ID'], $mnt_dataintegrity_code, false, false); // 500
    
    			$order = $modx->getObject('shk_order', $_REQUEST['MNT_TRANSACTION_ID']);
    			if (!$order)
    				monetaPayURLResponse($_REQUEST['MNT_ID'], $_REQUEST['MNT_TRANSACTION_ID'], $mnt_dataintegrity_code, false, true); // 402
    
    			// kassa
    			$purchases = $modx->getCollection('shk_purchases', array('order_id' => $order->id));
    
    			$inventoryPositions = array();
    			foreach($purchases as $purchase)
    			{
    				$inventoryPositions[] = array(
    					'name' => trim(preg_replace("/&?[a-z0-9]+;/i", "", htmlspecialchars($purchase->get('name')))),
    					'price' => $purchase->get('price'),
    					'quantity' => $purchase->get('count'),
    					'vatTag' => paw_kassa_VATNOVAT,
    				);
    			}
    			$kassa_inventory = json_encode($inventoryPositions);
    
    			$kassa_delivery = $order->delivery_price;
    
    			$customerEmail = '';
    			foreach (json_decode($order->contacts) as $contactInfo)
    				if ($contactInfo->name == 'email')
    				{
    					$customerEmail = $contactInfo->value;
    					break;
    				}
    
    			$mnt_dataintegrity_code = $modx->getOption('MNT_DATAINTEGRITY_CODE',$scriptProperties,null);
    			// end of kassa
    
    			if (isset($_REQUEST['MNT_ID']) && isset($_REQUEST['MNT_TRANSACTION_ID']) && isset($_REQUEST['MNT_OPERATION_ID'])
    				&& isset($_REQUEST['MNT_AMOUNT']) && isset($_REQUEST['MNT_CURRENCY_CODE']) && isset($_REQUEST['MNT_TEST_MODE'])
    				&& isset($_REQUEST['MNT_SIGNATURE'])) {
    				$signature = md5($_REQUEST['MNT_ID'] . $_REQUEST['MNT_TRANSACTION_ID'] . $_REQUEST['MNT_OPERATION_ID'] . $_REQUEST['MNT_AMOUNT'] . $_REQUEST['MNT_CURRENCY_CODE'] . $_REQUEST['MNT_TEST_MODE'] . $mnt_dataintegrity_code);
    				if ($_REQUEST['MNT_SIGNATURE'] == $signature) {
    					$order->set('status',6);
    					$order->save();
    					monetaPayURLResponse($_REQUEST['MNT_ID'], $_REQUEST['MNT_TRANSACTION_ID'], $mnt_dataintegrity_code,
    						true, false, true, true, $kassa_inventory, $customerEmail, $kassa_delivery);    		// 200
    				}
    				else {
    					monetaPayURLResponse($_REQUEST['MNT_ID'], $_REQUEST['MNT_TRANSACTION_ID'], $mnt_dataintegrity_code,
    						false, false);                                      	       							// 500
    				}
    			}
    			else {
    				monetaPayURLResponse($_REQUEST['MNT_ID'], $_REQUEST['MNT_TRANSACTION_ID'], $mnt_dataintegrity_code,
    					false, false);                                      	       								// 500
    			}
    			break;
    		case 'payment':
    			$order_id = null;
    			$mnt_id = trim($modx->getOption('MNT_ID',$scriptProperties,null));
    			$mnt_currency_code = trim($modx->getOption('MNT_CURRENCY_CODE',$scriptProperties,null));
    			$mnt_test_mode = (int)$modx->getOption('MNT_TEST_MODE',$scriptProperties,null);
    			$mnt_dataintegrity_code = trim($modx->getOption('MNT_DATAINTEGRITY_CODE',$scriptProperties,null));
    			$mnt_success_url = $modx->getOption('MNT_SUCCESS_URL',$scriptProperties,null);
    			$mnt_fail_url = $modx->getOption('MNT_FAIL_URL',$scriptProperties,null);
    
    			if (isset($_SESSION['shk_order_id'])) {
    				$order_id = $_SESSION['shk_order_id'];
    				$amount = number_format($_SESSION['shk_order_price'], 2, '.', '');
    			}
    			else {
    				$order_id = $_SESSION['shk_lastOrder']['id'];
    				$amount = number_format($_SESSION['shk_lastOrder']['price'], 2, '.', '');
    			}
    
    			if (!$order_id) {
    				return "Заказ не найден.";
    			}
    
    			$signature = md5($mnt_id . $order_id . $amount . $mnt_currency_code . $mnt_test_mode . $mnt_dataintegrity_code);
    
    			$order = $modx->getObject('shk_order', $order_id);
    			if (!$order) {
    				die('no shk_order object found');
    			}
    
    			//$order->set('status', 1);
    			//$order->save();
    
    			$output  = "<form action='https://".$modx->getOption('MNT_SERVER',$scriptProperties,null)."/assistant.htm' method='post'>";
    			$output .= "<input type='hidden' name='MNT_ID' value='".$mnt_id."'>";
    			$output .= "<input type='hidden' name='MNT_TRANSACTION_ID' value='".$order_id."'>";
    			$output .= "<input type='hidden' name='MNT_CURRENCY_CODE' value='".$mnt_currency_code."'>";
    			$output .= "<input type='hidden' name='MNT_AMOUNT' value='".$amount."'>";
    			$output .= "<input type='hidden' name='MNT_TEST_MODE' value='".$mnt_test_mode."'>";
    			$output .= "<input type='hidden' name='MNT_SIGNATURE' value='".$signature."'>";
    			$output .= "<input type='hidden' name='MNT_SUCCESS_URL' value='".$mnt_success_url."'>";
    			$output .= "<input type='hidden' name='MNT_FAIL_URL' value='".$mnt_fail_url."'>";
    			$output .= "<input type='submit' name='submit' value='Оплатить сейчас'>";
    
    			return $output;
    
    			break;
    		default:
    			break;
    	}
    }
    
    
  • Версия Shopkeeper3 3.2.7-pl3

  • Можно попробовать использовать процессор
    https://github.com/andchir/shopkeeper3/blob/master/core/components/shopkeeper3/processors/mgr/updateorderstatus.class.php
    но я не уверен. Вообще отправлять письмо после оплаты покупателю должна платежная система. Например, отправлять электронный чек.

    Похожая проблема с плагином "shk_updateInventory", если менять статус заказ вручную, количество товара уменьшается, а после изменения статуса через PayAnyWay этого не происходит.

    Потому что при смене статуса заказа нужно вызывать событие "OnSHKChangeStatus".

    $modx->invokeEvent('OnSHKChangeStatus', array('order_ids' => $order_ids, 'status' => $status));
    
  • @Andchir Платежная система отправляет и письмо об оплате, и чек. Вопрос почему письмо не отправляется от самого Shopkeeper. Сейчас для меня важнее вопрос уменьшения количества товара. Я попробовал вставить вашу строчку в файл payanyway.inc.php (полный файл выше) так

    					$order->set('status',6);
    					$order->save();
                                            $modx->invokeEvent('OnSHKChangeStatus', array('order_id' => $order_id, 'status' => $status));
    
    

    но ничего не изменилось. В php плохо разбираюсь. Подскажите, куда ее нужно добавить, чтобы работало?

  • Вопрос почему письмо не отправляется от самого Shopkeeper.

    Я уже ответил выше. Нужно попробовать использовать процессор. Если не получится, значит такого функционала нет.

    Я попробовал вставить вашу строчку в файл payanyway.inc.php (полный файл выше) так

    Вы зачем-то изменили название одного параметра. Нужно так:

    $order->save();
    $modx->invokeEvent('OnSHKChangeStatus', array('order_ids' => array($order->get('id')), 'status' => $order->get('status')));
    
 

Последние комментарии