yoomoney_api-2.5.2/yoo_ubercart/yoo_ubercart_api.module
yoo_ubercart/yoo_ubercart_api.module
<?php
use YooKassa\Common\Exceptions\ApiException;
use YooKassa\Model\Payment;
use YooKassa\Model\PaymentStatus;
use YooKassa\Request\Payments\CreatePaymentRequest;
use YooKassa\Request\Payments\CreatePaymentRequestBuilder;
use YooKassa\Request\Payments\Payment\CreateCaptureRequest;
use YooKassa\Request\Payments\Payment\CreateCaptureRequestBuilder;
require_once MODULE_PATH.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';
require_once MODULE_PATH.DIRECTORY_SEPARATOR.'YooMoneyLogger.php';
require_once MODULE_PATH.DIRECTORY_SEPARATOR.'YooMoneyKassaLogger.php';
define('YOOMONEY_EVENT_ORDER_UPDATE', 'update');
/**
* @param $event
* @param $order
* @param $new_status
*/
function yoo_ubercart_api_uc_order($event, $order, $new_status)
{
if ($event != YOOMONEY_EVENT_ORDER_UPDATE) {
return;
}
if (!yoomoney_api_is_need_second_receipt($new_status)) {
return;
}
$orderInfo = array(
'order_id' => $order->order_id,
'user_email' => empty($order->primary_email) ? null : $order->primary_email,
'user_phone' => empty($order->billing_phone) ? null : $order->billing_phone,
);
$result = yoomoney_api_send_second_receipt($orderInfo);
if (!$result->is_send) {
return;
}
uc_order_comment_save($order->order_id, $order->uid, $result->message, 'admin', $status = $new_status);
}
/**
* Implements hook_uc_payment_method().
*
* @see uc_payment_method_yoomoney_api()
*/
function yoo_ubercart_api_uc_payment_method()
{
$payment_methods = array();
$icon_name = 'yookassa-logo';
$icon = theme(
'image',
array(
'path' => drupal_get_path('module', 'yoo_ubercart_api').'/images/'.$icon_name.'.png',
'attributes' => array('class' => array('yoo-ubercart-logo')),
)
);
$display_title = t('YooKassa (bank card, e-money, etc.)');
$display_title .= '<br/>'.$icon;
$payment_methods['yoo_ubercart_api'] = array(
'name' => t('YooMoney'),
'title' => $display_title,
'review' => t('YooMoney'),
'desc' => t('Redirect to YooMoney to pay by credit card or pay terminals or e-money.'),
'callback' => 'uc_payment_method_yoo_ubercart_api',
'redirect' => 'yoo_ubercart_api_form',
'weight' => 3,
'checkout' => true,
);
return $payment_methods;
}
/**
* @param array $form
* @param array $form_state
* @param $order
*
* @return array
* @throws Exception
*/
function yoo_ubercart_api_form($form, &$form_state, $order)
{
global $user;
$kassaLogger = getKassaLog();
$kassaLogger->sendHeka(array('payment.create.init'));
if (isset($form_state['input']['confirmation'])) {
drupal_goto($form_state['input']['confirmation']);
uc_order_update_status($order->order_id, 'payment_received');
}
$apiClient = yoomoney_api__common__get_api_client();
$amount = $order->order_total;
$builder = yoo_ubercart_api_get_create_payment_request_builder($order, $amount);
$paymentRequest = $builder->build();
try {
$kassaLogger->sendHeka(array('payment.request.init'));
$response = $apiClient->createPayment($paymentRequest);
if (
$response !== null
&& $response->status !== PaymentStatus::CANCELED
) {
$transaction = new YooMoneyApiTransaction();
$transaction->uid = $user->uid;
$transaction->amount = $order->order_total;
$transaction->mail = isset($user->mail) ? $user->mail : $order->primary_email;
$transaction->order_id = $order->order_id;
$transaction->payment_id = $response->getId();
$transaction->status = $response->getStatus();
if (!yoomoney_api_transaction_save($transaction)) {
$error_message = t('Can not save transaction.');
// show message to the user
drupal_set_message(t('Payment failed: %message', array('%message' => $error_message)), 'error');
// log error to watchdog
watchdog('yoo_ubercart', 'Payment failed: %message', array('%message' => $error_message),
WATCHDOG_WARNING);
// redirect to fail page
$cancel_url = url('yoomoney_api/fail');
$kassaLogger->sendHeka(array('payment.create.fail', 'payment.request.success'));
drupal_goto($cancel_url);
}
uc_order_update_status($order->order_id, 'pending');
$confirmationUrl = $response->confirmation->confirmationUrl;
$form['actions']['submit']['#submit'][] = 'yoo_ubercart_api_redirect_handler';
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Process payment'),
'#attributes' => array('onclick' => "location.href = '{$confirmationUrl}'; return false;"),
);
$kassaLogger->sendHeka(array('payment.request.success', 'payment.redirect.init'));
return $form;
} else {
drupal_set_message('Невозможно заплатить этим методом', 'error');
}
} catch (ApiException $e) {
getKassaLog()->sendAlertLog('Failed to create payment', array(
'methodid' => 'POST/createPayment',
'exception' => $e,
), array('payment.request.fail', 'payment.create.fail'));
YooMoneyLogger::error('Api error: '.$e->getMessage());
drupal_set_message('Unable to pay with this method.', 'error');
}
$kassaLogger->sendHeka(array('payment.create.fail', 'payment.request.fail'));
return $form;
}
/**
* @param $order
* @param $amount
*
* @return \YooKassa\Request\Payments\CreatePaymentRequestBuilder
*/
function yoo_ubercart_api_get_create_payment_request_builder($order, $amount)
{
$confirmationType = \YooKassa\Model\ConfirmationType::REDIRECT;
$builder = CreatePaymentRequest::builder()
->setAmount($amount)
->setCapture(!yoomoney_api__common__is_enable_hold_mode())
->setDescription(yoo_ubercart_api_create_description($order))
->setConfirmation(array(
'type' => $confirmationType,
'returnUrl' => yoo_ubercart_api_get_return_url($order),
))
->setMetadata(array(
'cms_name' => CMS_NAME_UBERCART,
'module_version' => YOOMONEY_MODULE_VERSION,
));
yoo_ubercart_api_set_receipt_if_needed($builder, $order);
return $builder;
}
/**
* @param CreatePaymentRequestBuilder|CreateCaptureRequestBuilder $builder
* @param $order
*/
function yoo_ubercart_api_set_receipt_if_needed($builder, $order)
{
if (!module_exists('uc_taxes') && !variable_get('yoomoney_api_send_check', false)) {
return;
}
$kassaLogger = getKassaLog();
$kassaLogger->sendHeka(array('receipt.create.init'));
$tax = uc_taxes_uc_calculate_tax($order);
$builder->setReceiptEmail($order->primary_email);
if (count($tax)) {
$tax = current($tax);
}
foreach ($order->products as $product) {
$tax_id = isset($tax->id) ? $tax->id : 0;
$tax = ($tax_id && variable_get('yoomoney_api_kassa_tax_'.$tax_id) ? variable_get(
'yoomoney_api_kassa_tax_'.$tax_id
) : YOOMONEY_API_DEFAULT_TAX_RATE_ID);
$builder->addReceiptItem($product->title, $product->price, $product->qty, $tax,
variable_get('yoomoney_kassa_payment_mode'),
variable_get('yoomoney_kassa_payment_subject'));
}
foreach ($order->line_items as $item) {
if ($item['type'] === 'subtotal') {
continue;
}
$tax_id = isset($tax->id) ? $tax->id : 0;
$amount = $item['amount'] * (isset($tax->id) ? (1 + $tax->data['tax_rate']) : 1);
$tax = ($tax_id && variable_get('yoomoney_api_kassa_tax_'.$tax_id) ? variable_get(
'yoomoney_api_kassa_tax_'.$tax_id
) : YOOMONEY_API_DEFAULT_TAX_RATE_ID);
$builder->addReceiptShipping($item['title'], $amount, $tax,
variable_get('yoomoney_kassa_delivery_payment_mode'),
variable_get('yoomoney_kassa_delivery_payment_subject'));
}
$kassaLogger->sendHeka(array('receipt.create.success'));
}
/**
* Implements hook_yoomoney_api_shop_params_alter().
*
* @param $params
*/
function yoo_ubercart_api_yoomoney_api_shop_params_alter(&$params)
{
$params['shop-desc'] = t('Payments for order No').$params['order_id'];
}
/**
* @param $op
* @param $order
* @param null $form
* @param null $form_state
*
* @return array|null
*/
function uc_payment_method_yoo_ubercart_api($op, &$order, $form = array(), &$form_state = array())
{
return array();
}
/**
* Process successful payment to update Ubercart order.
* Implements hook_yoomoney_api_process_payment_alter().
*
* @param array $payment
*/
function yoo_ubercart_api_yoomoney_api_process_payment_alter(&$payment)
{
/** @var YooMoneyApiTransaction $transaction */
$transaction = $payment['transaction'];
$order = uc_order_load($transaction->order_id);
if ($order) {
//print_r($order);
uc_cart_complete_sale($order);
uc_cart_empty($order->uid);
uc_order_update_status($order->order_id, 'payment_received');
$payment['success'] = true;
} else {
$payment['success'] = false;
$payment['error'] = 'Can not find order with id '.$transaction->order_id;
}
}
function yoo_ubercart_api_get_return_url($order)
{
return url(
'yoomoney_api/ubercart/return',
array(
'absolute' => true,
'query' => array('orderId' => $order->order_id),
)
);
}
/**
* @param $orderInfo
*
* @return bool|string
*/
function yoo_ubercart_api_create_description($orderInfo)
{
$descriptionTemplate = variable_get('yoomoney_api_description_template', t('Payment for order No. %order_id%'));
$replace = array();
foreach ($orderInfo as $key => $value) {
if (is_scalar($value)) {
$replace['%'.$key.'%'] = $value;
}
}
$description = strtr($descriptionTemplate, $replace);
return mb_substr($description, 0, Payment::MAX_LENGTH_DESCRIPTION);
}
/**
* @param \YooKassa\Model\PaymentInterface $payment
* @param $order
* @throws Exception
*/
function yoo_ubercart_api_capture_payment($payment, $order)
{
$kassaLogger = getKassaLog();
$kassaLogger->sendHeka(array('capture.create.init'));
$apiClient = yoomoney_api__common__get_api_client();
try {
$builder = CreateCaptureRequest::builder();
$amount = $order->order_total;
$builder->setAmount($amount);
yoo_ubercart_api_set_receipt_if_needed($builder, $order);
$request = $builder->build();
$response = $apiClient->capturePayment($request, $payment->getId());
} catch (\Exception $e) {
$this->getKassaLog()->sendAlertLog('Failed to capture payment', array(
'methodid' => 'POST/capturePayment',
'exception' => $e,
), array('capture.create.fail'));
YooMoneyLogger::error('Capture error: ' . $e->getMessage());
$response = $payment;
}
yoomoney_api_common_check_value_is_not_empty($response, '400 Bad Request', 'Empty payment info');
if ($response->getStatus() !== \YooKassa\Model\PaymentStatus::SUCCEEDED) {
YooMoneyLogger::error('Capture payment error: capture failed');
$kassaLogger->sendHeka(array('capture.create.fail'));
return;
}
yoomoney_api_update_transaction_status($response->getId(), $response->getStatus());
uc_order_comment_save($order->order_id, 0, t('Вы подтвердили платёж в ЮKassa.'));
$kassaLogger->sendHeka(array('capture.create.success', 'shop.'.$kassaLogger->getShopId().'.payment.succeeded'));
echo "OK";
exit();
}
/**
* @param string $paymentId
* @param $order
*/
function yoo_ubercart_api_cancel_payment($paymentId, $order)
{
$kassaLogger = getKassaLog();
$kassaLogger->sendHeka(array('cancel.create.init'));;
$apiClient = yoomoney_api__common__get_api_client();
try {
$response = $apiClient->cancelPayment($paymentId);
} catch (Exception $e) {
$this->getKassaLog()->sendAlertLog('Failed to cancel payment', array(
'methodid' => 'POST/cancelPayment',
'exception' => $e,
), array('cancel.create.fail'));
YooMoneyLogger::error('Cancel payment error: ' . $e->getMessage());
}
if (!$response || $response->getStatus() !== PaymentStatus::CANCELED) {
YooMoneyLogger::error('Cancel payment error: cancel failed');
$kassaLogger->sendHeka(array('cancel.create.fail'));
return;
}
uc_order_update_status($order->order_id, YOOMONEY_API_ORDER_STATUS_CANCELED);
yoomoney_api_update_transaction_status($paymentId, PaymentStatus::CANCELED);
uc_order_comment_save($order->order_id, 0, t('Вы отменили платёж в ЮKassa. Деньги вернутся клиенту.'));
$kassaLogger->sendHeka(array('cancel.create.success', 'shop.'.$kassaLogger->getShopId().'.payment.canceled'));
echo "OK";
exit();
}
