Отложенный платеж

Материал из Umicms
Версия от 14:27, 30 марта 2014; Stexe (обсуждение | вклад)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к:навигация, поиск

Задача: Реализовать функционал отложенного платежа заказа, то есть возможность оплаты заказа после прохождения шагов оформления заказа

Реализация:
После оформления заказа в его поле будет записываться ссылка, при переходе на которую будет отображаться форма для оплаты заказа в выбранной платежной системе. При желании можно поместить данную ссылку в письмо-уведомление о смене статуса оплаты заказа.

В модуле "Шаблоны данных" в тип данных "Заказ" добавим поле типа "Строка" с именем "Ссылка на оплату заказа" и идентификатором "pay_order_link".
В файл classes\modules\emarket\__custom.php добавим определения метода формирования данных для платежной системы и обработчик события для записи ссылки в поле "Ссылка на оплату заказа".

/* Возращает данные для формирования формы оплаты заказа покупателем
*  $order_id - id заказа
*  $template - название шаблона для обработки данных
*/
public function payOrder($order_id = false, $template = 'default') 
{
	if ( !$order_id )
	{
		$order_id = getRequest('order_id');
	}
	if ( !$template )
	{
		$template = getRequest('template');
	}
	
	//Получить объект заказа
	$order = order::get($order_id);
	if ( !($order instanceof order) )
	{
		throw new publicException("Заказ с id - '{$order_id}' не существует");
	}
	//Из объекта заказа получить id способа оплаты
	$payment_id = $order->getValue('payment_id');
	//По id способа оплаты получить объект способа оплаты
	$payment = payment::get($payment_id, $order);
	if( !($payment instanceof payment) )
	{
		throw new publicException("В заказе c id - '{$order_id}' не выбран способ оплаты");
	}
	
	//Если статус оплаты не "Подтвердена" или не "Принята"
	//Вернуть данные для формирования формы оплаты заказа
	$payment_status_id = $order->getPaymentStatus();
	$payment_status_acc = order::getStatusByCode('accepted', 'order_payment_status');
	$payment_status_val = order::getStatusByCode('validated', 'order_payment_status');
	
	if ( $payment_status_id === NULL ||
		($payment_status_id != $payment_status_acc && 
		 $payment_status_id != $payment_status_val) )
	{
		$result_arr = $payment->process($template);
		$result_arr['payment_name'] = $payment->getCodeName();
		return $result_arr;
	}else
	{
		throw new publicException("Оплата заказа с id - '{$order_id}' уже произведена");
	}
	
}

public function onGotNewOrder($event)
{
	if( $event->getMode() == "after" &&
		$event->getParam("old-status-id") == false &&
		$event->getParam("new-status-id") == order::getStatusByCode('waiting') ) 
	{
		$order = $event->getRef("order");
		$domain = $order->getDomain();
		if ( !$domain )
		{
			$domain = cmsController::getInstance()->getCurrentDomain();
		}
		$domain_host = $domain->getHost();
		$link = "http://{$domain_host}/emarket/payOrder/?order_id={$order->getId()}";
		$order->setValue('pay_order_link', $link);
	}
}

В файл \classes\modules\emarket\permissions.custom.php добавим следующий код:

<?php
    $permissions = array(
		'purchasing' => array(
			'payOrder', 'onGotNewOrder'));

Также, в файл \classes\modules\emarket\custom_events.php добавим код назначения обработчика события:

<?php
    new umiEventListener('order-status-changed', 'emarket', 'onGotNewOrder');

Добавим XSL-шаблоны для отображения формы оплаты:

<xsl:template match="result[@module = 'emarket'][@method = 'payOrder']">
	<xsl:apply-templates select="document('udata://emarket/payOrder')/udata" />
</xsl:template>

<xsl:template match="udata[@module = 'emarket'][@method = 'payOrder'][payment_name = 'yandex']">
	<form action="{formAction}" method="post">
		<input type="hidden" name="shopId"	value="{shopId}" />
		<input type="hidden" name="Sum"		value="{Sum}" />
		<input type="hidden" name="BankId"	value="{BankId}" />
		<input type="hidden" name="scid"	value="{scid}" />
		<input type="hidden" name="CustomerNumber" value="{CustomerNumber}" />
		<input type="hidden" name="order-id" value="{orderId}" />

		<div>
			<xsl:text>Нажмите кнопку 'Оплатить' для перехода на сайт платежной системы Yandex.</xsl:text>
		</div>

		<div>
			<input type="submit" value="Оплатить" class="button big" />
		</div>
	</form>
</xsl:template>

В данном случае приведен пример шаблона отображения формы оплаты для платежной системы Яндекс.Деньги. Шаблоны для других платежных систем можно найти в файле \templates\demodizzy\xslt\modules\emarket\purchase\payment.xsl в демонстрационном дизайне "Современный интернет-магазин 'Demodizzy'".
Единственное различие данных шаблонов будет заключаться в значении для атрибута match.
'Demodizzy':

<xsl:template match="purchasing[@stage = 'payment'][@step = 'yandex']">

Шаблон для метода payOrder():

<xsl:template match="udata[@module = 'emarket'][@method = 'payOrder'][payment_name = 'yandex']">

Файлы демонстрационного дизайна "Современный интернет-магазин 'Demodizzy'" можно скачать здесь Файл:Demodizzy.zip