Отложенный платеж
Задача: Реализовать функционал отложенного платежа заказа, то есть возможность оплаты заказа после прохождения шагов оформления заказа
Реализация:
После оформления заказа в его поле будет записываться ссылка, при переходе на которую будет отображаться форма для оплаты заказа в выбранной платежной системе. При желании можно поместить данную ссылку в письмо-уведомление о смене статуса оплаты заказа.
В модуле "Шаблоны данных" в тип данных "Заказ" добавим поле типа "Строка" с именем "Ссылка на оплату заказа" и идентификатором "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']">