mirror of
https://github.com/valitydev/rbkmoney-cms-drupal-commerce.git
synced 2024-11-06 02:05:17 +00:00
498 lines
17 KiB
Plaintext
498 lines
17 KiB
Plaintext
<?php
|
||
|
||
module_load_include('inc', 'commerce_rbkmoney', 'includes/commerce_rbkmoney_settings');
|
||
|
||
/**
|
||
* Implements hook_permission().
|
||
*/
|
||
function commerce_rbkmoney_permission()
|
||
{
|
||
return [
|
||
'administer commerce_rbkmoney' => [
|
||
'title' => t('Administer Commerce ' . COMPANY_NAME),
|
||
'description' => t('Access the Commerce ' . COMPANY_NAME . ' settings page'),
|
||
],
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Implements hook_menu().
|
||
*/
|
||
function commerce_rbkmoney_menu()
|
||
{
|
||
$items['admin/commerce/config/rbkmoney'] = [
|
||
'title' => 'RBKmoney configuration',
|
||
'page callback' => 'drupal_get_form',
|
||
'page arguments' => ['commerce_rbkmoney_config'],
|
||
'access arguments' => ['administer commerce_rbkmoney'],
|
||
'type' => MENU_NORMAL_ITEM,
|
||
];
|
||
|
||
$items['commerce/rbkmoney/callback/result'] = [
|
||
'title' => 'Status',
|
||
'page callback' => 'commerce_rbkmoney_callback_result',
|
||
'access arguments' => ['access content'],
|
||
'type' => MENU_CALLBACK,
|
||
'file' => 'includes/commerce_rbkmoney_callback.pages.inc',
|
||
];
|
||
|
||
$items['commerce/rbkmoney/success'] = [
|
||
'title' => 'Internal Data',
|
||
'page callback' => 'commerce_rbkmoney_payment_end',
|
||
'page arguments' => ['success'],
|
||
'access arguments' => ['access content'],
|
||
'type' => MENU_CALLBACK,
|
||
];
|
||
$items['commerce/rbkmoney/fail'] = [
|
||
'title' => 'Internal Data',
|
||
'page callback' => 'commerce_rbkmoney_payment_end',
|
||
'page arguments' => ['fail'],
|
||
'access arguments' => ['access content'],
|
||
'type' => MENU_CALLBACK,
|
||
];
|
||
|
||
return $items;
|
||
}
|
||
|
||
/**
|
||
* Implements hook_commerce_payment_method_info().
|
||
*/
|
||
function commerce_rbkmoney_commerce_payment_method_info()
|
||
{
|
||
$payment_methods = [];
|
||
// The system name of the payment method.
|
||
$payment_methods[MODULE_NAME] = [
|
||
// Name of payment method to display in the admin area.
|
||
'title' => t(COMPANY_NAME),
|
||
// The description of the payment method. Optional.
|
||
'description' => t('Payment via ' . COMPANY_NAME . ' payment system'),
|
||
// TRUE or FALSE indicating whether or not payments can be processed
|
||
// via this payment method through the administrative payment
|
||
// terminal on an order’s Payment tab Optional. Defaults to TRUE.
|
||
'terminal' => FALSE,
|
||
// Whether the buyer to leave the website for payment by this method.
|
||
// Optional. Defaults to FALSE.
|
||
'offsite' => TRUE,
|
||
// As a payment method when you enable the module: TRUE — enabled, FALSE — disabled
|
||
// (the default). Optional.
|
||
'active' => TRUE,
|
||
// Automatically redirect to third party website for payment in this way.
|
||
// Optional. Defaults to FALSE.
|
||
'offsite_autoredirect' => FALSE,
|
||
];
|
||
|
||
return $payment_methods;
|
||
}
|
||
|
||
/**
|
||
* Payment method settings form.
|
||
*/
|
||
function commerce_rbkmoney_config()
|
||
{
|
||
$form['commerce_rbkmoney_help'] = [
|
||
'#markup' => t('Настройки платежного модуля RBKmoney'),
|
||
];
|
||
|
||
$form['vertical_tabs'] = array(
|
||
'#type' => 'vertical_tabs',
|
||
'#default_tab' => 'edit-tab1',
|
||
);
|
||
|
||
$form['tab1'] = array(
|
||
'#type' => 'fieldset',
|
||
'#title' => t('Обязательные настройки'),
|
||
'#collapsible' => TRUE,
|
||
'#group' => 'vertical_tabs',
|
||
);
|
||
|
||
$form['tab1']['commerce_rbkmoney_shop_id'] = [
|
||
'#type' => 'textfield',
|
||
'#title' => t('ID магазина'),
|
||
'#default_value' => variable_get('commerce_rbkmoney_shop_id', 'Shop_ID'),
|
||
'#description' => t(''),
|
||
'#required' => TRUE,
|
||
];
|
||
|
||
$form['tab1']['commerce_rbkmoney_merchant_callback_public_key'] = [
|
||
'#type' => 'textarea',
|
||
'#title' => t('Ключ подписи получаемых на Webhook уведомлений из <a href=\'!dblog\'>https://dashboard.rbk.money/api/webhooks</a>',
|
||
['!dblog' => "https://dashboard.rbk.money/api/webhooks"]),
|
||
'#default_value' => MERCHANT_CALLBACK_PUBLIC_KEY,
|
||
'#description' => t(''),
|
||
'#rows' => 10,
|
||
'#cols' => 10,
|
||
'#resizable' => FALSE,
|
||
'#weight' => 10,
|
||
'#required' => TRUE,
|
||
];
|
||
|
||
$form['tab1']['commerce_rbkmoney_merchant_private_key'] = [
|
||
'#type' => 'textarea',
|
||
'#title' => t('Ваш ключ для доступа к API из <a href=\'!dblog\'>https://dashboard.rbk.money/api/key</a>',
|
||
['!dblog' => "https://dashboard.rbk.money/api/key"]),
|
||
'#default_value' => MERCHANT_PRIVATE_KEY,
|
||
'#description' => t(''),
|
||
'#rows' => 10,
|
||
'#cols' => 10,
|
||
'#resizable' => FALSE,
|
||
'#weight' => 10,
|
||
'#required' => TRUE,
|
||
];
|
||
|
||
$form['tab2'] = array(
|
||
'#type' => 'fieldset',
|
||
'#title' => t('Кастомизация формы оплаты'),
|
||
'#collapsible' => TRUE,
|
||
'#group' => 'vertical_tabs',
|
||
);
|
||
|
||
$form['tab2']['commerce_rbkmoney_payform_button_label'] = [
|
||
'#type' => 'textfield',
|
||
'#title' => t('Текст кнопки открытия формы оплаты'),
|
||
'#default_value' => variable_get('commerce_rbkmoney_payform_button_label', ''),
|
||
'#description' => t(''),
|
||
'#required' => FALSE,
|
||
];
|
||
|
||
$form['tab2']['commerce_rbkmoney_payform_description'] = [
|
||
'#type' => 'textfield',
|
||
'#title' => t('Описание в форме оплаты'),
|
||
'#default_value' => variable_get('commerce_rbkmoney_payform_description', ''),
|
||
'#description' => t(''),
|
||
'#required' => FALSE,
|
||
];
|
||
|
||
$form['tab2']['commerce_rbkmoney_payform_company_name'] = [
|
||
'#type' => 'textfield',
|
||
'#title' => t('Название магазина для отображения на форме оплаты'),
|
||
'#default_value' => variable_get('commerce_rbkmoney_payform_company_name', ''),
|
||
'#description' => t(''),
|
||
'#required' => FALSE,
|
||
];
|
||
|
||
$form['tab2']['commerce_rbkmoney_payform_css_button'] = [
|
||
'#type' => 'textarea',
|
||
'#title' => t('Стилизация кнопки открытия формы оплаты'),
|
||
'#default_value' => variable_get('commerce_rbkmoney_payform_css_button', PAYMENT_FORM_DEFAULT_CSS_BUTTON),
|
||
'#description' => t(''),
|
||
'#rows' => 10,
|
||
'#cols' => 10,
|
||
'#resizable' => FALSE,
|
||
'#weight' => 10,
|
||
'#required' => FALSE,
|
||
];
|
||
|
||
$form['tab3'] = array(
|
||
'#type' => 'fieldset',
|
||
'#title' => t('Дополнительные настройки'),
|
||
'#collapsible' => TRUE,
|
||
'#group' => 'vertical_tabs',
|
||
);
|
||
|
||
$form['tab3']['common_settings']['commerce_rbkmoney_log'] = [
|
||
'#type' => 'radios',
|
||
'#title' => t('Сохранять лог RBKmoney API в <a href=\'!dblog\'>system log</a>',
|
||
['!dblog' => url(BASE_URL . '/#overlay=admin/reports/dblog')]),
|
||
'#options' => [1 => t('Yes'), 0 => t('No')],
|
||
'#default_value' => variable_get('commerce_rbkmoney_log', 1),
|
||
];
|
||
|
||
$form['tab4'] = array(
|
||
'#type' => 'fieldset',
|
||
'#title' => t('Документация'),
|
||
'#collapsible' => TRUE,
|
||
'#group' => 'vertical_tabs',
|
||
);
|
||
|
||
$form['tab4']['docs_integrations'] = array(
|
||
'#type' => 'item',
|
||
'#markup' => t(l('Документация по интеграции', 'https://developer.rbk.money/',
|
||
['attributes' =>
|
||
['target' => '_blank']
|
||
])),
|
||
);
|
||
|
||
$form['tab4']['docs_webhooks'] = array(
|
||
'#type' => 'item',
|
||
'#markup' => t(l('Документация для работы с вебхуками', 'https://rbkmoney.github.io/webhooks-events-api/',
|
||
['attributes' =>
|
||
['target' => '_blank']
|
||
])),
|
||
);
|
||
|
||
$form['tab4']['docs_checkout'] = array(
|
||
'#type' => 'item',
|
||
'#markup' => t(l('Документация по кастомизации платежной формы', 'https://developer.rbk.money/docs/payments/checkout/#html-api',
|
||
['attributes' =>
|
||
['target' => '_blank']
|
||
])),
|
||
);
|
||
|
||
return system_settings_form($form);
|
||
}
|
||
|
||
|
||
/*
|
||
* Payment method callback
|
||
*/
|
||
function commerce_rbkmoney_redirect_form($form, &$form_state, $order, $payment_method)
|
||
{
|
||
if ($order->order_id > 0 && $payment_method['method_id'] == MODULE_NAME) {
|
||
|
||
if (empty($_SESSION[API_INVOICE_ID])) {
|
||
$response = _commerce_rbkmoney_create_invoice($order);
|
||
$response_decode = drupal_json_decode($response['body']);
|
||
$invoice_id = !empty($response_decode['invoice']['id']) ? $response_decode['invoice']['id'] : '';
|
||
$access_token = !empty($response_decode['invoiceAccessToken']['payload']) ? $response_decode['invoiceAccessToken']['payload'] : '';
|
||
$_SESSION[API_INVOICE_ID] = $invoice_id;
|
||
} else {
|
||
$invoice_id = $_SESSION[API_INVOICE_ID];
|
||
}
|
||
|
||
|
||
|
||
$company_name = (!empty(variable_get('commerce_rbkmoney_payform_company_name'))) ? 'data-name="' . variable_get('commerce_rbkmoney_payform_company_name') . '"' : '';
|
||
$button_label = (!empty(variable_get('commerce_rbkmoney_payform_button_label'))) ? 'data-label="' . variable_get('commerce_rbkmoney_payform_button_label') . '"' : '';
|
||
$description = (!empty(variable_get('commerce_rbkmoney_payform_description'))) ? 'data-description="' . variable_get('commerce_rbkmoney_payform_description') . '"' : '';
|
||
|
||
$action = BASE_URL . '/commerce/rbkmoney/success?order_id=' . $order->order_id;
|
||
|
||
$payframe = '<script src="' . PAYMENT_FORM_URL . '" class="rbkmoney-checkout"
|
||
data-invoice-id="' . $invoice_id . '"
|
||
data-invoice-access-token="' . $access_token . '"
|
||
' . $company_name . '
|
||
' . $button_label . '
|
||
' . $description . '
|
||
>
|
||
</script>';
|
||
$css_button = '<style>' . strip_tags(variable_get('commerce_rbkmoney_payform_css_button', PAYMENT_FORM_DEFAULT_CSS_BUTTON)) . '</style>';
|
||
|
||
$form['#action'] = $action;
|
||
$text = $css_button . '<form></form>';
|
||
$form['info'] = ['#markup' => $text];
|
||
$form['order_id'] = ['#type' => 'hidden', '#value' => $order->order_id];
|
||
|
||
$form['payment_details']['#prefix'] = '<div id="payment-details"><form action="' . $action . '" method="' . HTTP_METHOD_POST . '">' . $payframe;
|
||
$form['payment_details']['#suffix'] = '</form></div>';
|
||
}
|
||
|
||
return $form;
|
||
}
|
||
|
||
/**
|
||
* Payment method callback: submit form.
|
||
*/
|
||
function commerce_rbkmoney_submit_form($payment_method, $pane_values, $checkout_pane, $order)
|
||
{
|
||
$form = [];
|
||
$text = theme('image',
|
||
[
|
||
'path' => PAYMENT_METHOD_PATH_IMG_LOGO,
|
||
'alt' => t(COMPANY_NAME),
|
||
'title' => t(COMPANY_NAME),
|
||
'attributes' => ['class' => 'rbkmoney-logo']
|
||
]
|
||
);
|
||
$text .= '<div class="rbkmoney">' . t('Pay with credit card') . '<br /></div>';
|
||
$form['info'] = ['#markup' => $text];
|
||
|
||
return $form;
|
||
}
|
||
|
||
function _commerce_rbkmoney_update_status_order($order_id, $status)
|
||
{
|
||
|
||
$order = commerce_order_load($order_id);
|
||
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
|
||
$amount = _commerce_rbkmoney_prepare_amount($order_wrapper);
|
||
$currency_code = _commerce_rbkmoney_prepare_currency($order_wrapper);
|
||
|
||
switch ($status) {
|
||
|
||
case RBKMONEY_STATUS_FAILED:
|
||
$transaction = commerce_payment_transaction_new(MODULE_NAME, $order->order_id);
|
||
$transaction->instance_id = $order->data['payment_method'];
|
||
$transaction->amount = $amount;
|
||
$transaction->currency_code = $currency_code;
|
||
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
|
||
$transaction->message = t('Response from RBK Money: failure');
|
||
commerce_payment_transaction_save($transaction);
|
||
_commerce_rbkmoney_logger(MODULE_NAME, "status: {" . RBKMONEY_STATUS_FAILED . "}; data: <pre>%log</pre>", ['%log' => var_export(['order_id' => $order_id, 'status' => $status], TRUE)]);
|
||
break;
|
||
|
||
case RBKMONEY_STATUS_SUCCESS:
|
||
$transaction = commerce_payment_transaction_new(MODULE_NAME, $order->order_id);
|
||
$transaction->instance_id = $order->data['payment_method'];
|
||
$transaction->amount = $amount;
|
||
$transaction->currency_code = $currency_code;
|
||
$transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
|
||
$transaction->message = t('Response from RBK Money: successful');
|
||
commerce_payment_transaction_save($transaction);
|
||
_commerce_rbkmoney_logger(MODULE_NAME, "status: {" . RBKMONEY_STATUS_SUCCESS . "}; data: <pre>%log</pre>", ['%log' => var_export(['order_id' => $order_id, 'status' => $status], TRUE)]);
|
||
break;
|
||
|
||
default:
|
||
_commerce_rbkmoney_logger(MODULE_NAME, "Fail update status; data: <pre>%log</pre>", ['%log' => var_export(['order_id' => $order_id, 'status' => $status], TRUE)]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Callback redirect from RBKmoney site.
|
||
*/
|
||
function commerce_rbkmoney_payment_end($arg)
|
||
{
|
||
if (!empty($_SESSION[API_INVOICE_ID])) unset($_SESSION[API_INVOICE_ID]);
|
||
if (empty($_GET['order_id'])) $arg = 'fail';
|
||
|
||
switch ($arg) {
|
||
case "success":
|
||
drupal_set_message(t("Your payment processed."));
|
||
drupal_goto('cart');
|
||
break;
|
||
case "fail":
|
||
drupal_set_message(t("Your payment has been declined."), 'error');
|
||
drupal_goto('cart');
|
||
break;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
function _commerce_rbkmoney_create_invoice($order)
|
||
{
|
||
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
|
||
|
||
$data = [
|
||
'shopID' => variable_get('commerce_rbkmoney_shop_id'),
|
||
'amount' => _commerce_rbkmoney_prepare_amount($order_wrapper),
|
||
'metadata' => _commerce_rbkmoney_prepare_metadata($order),
|
||
'dueDate' => _commerce_rbkmoney_prepare_due_date(),
|
||
'currency' => _commerce_rbkmoney_prepare_currency($order_wrapper),
|
||
'product' => $order->order_id,
|
||
'description' => "",
|
||
];
|
||
|
||
$url = _commerce_rbkmoney_prepare_api_url('processing/invoices');
|
||
$headers = _commerce_rbkmoney_prepare_headers();
|
||
$response = _commerce_rbkmoney_send($url, $headers, drupal_json_encode($data), 'init_invoice');
|
||
|
||
if ($response['http_code'] != HTTP_CODE_CREATED) {
|
||
drupal_set_message(t('An error occurred while creating invoice'), 'error');
|
||
drupal_goto('cart');
|
||
}
|
||
|
||
return $response;
|
||
}
|
||
|
||
function _commerce_rbkmoney_prepare_headers()
|
||
{
|
||
$headers = [];
|
||
$headers[] = 'X-Request-ID: ' . uniqid();
|
||
$headers[] = 'Authorization: Bearer ' . MERCHANT_PRIVATE_KEY;
|
||
$headers[] = 'Content-type: application/json; charset=utf-8';
|
||
$headers[] = 'Accept: application/json';
|
||
return $headers;
|
||
}
|
||
|
||
/**
|
||
* Prepare due date
|
||
* @return string
|
||
*/
|
||
function _commerce_rbkmoney_prepare_due_date()
|
||
{
|
||
date_default_timezone_set('UTC');
|
||
return date(CREATE_INVOICE_TEMPLATE_DUE_DATE, strtotime(CREATE_INVOICE_DUE_DATE));
|
||
}
|
||
|
||
/**
|
||
* Prepare metadata
|
||
*
|
||
* @param $order Object
|
||
* @return array
|
||
*/
|
||
function _commerce_rbkmoney_prepare_metadata($order)
|
||
{
|
||
return [
|
||
'cms' => 'drupal',
|
||
'cms_version' => VERSION,
|
||
'module' => MODULE_NAME,
|
||
'order_id' => $order->order_id,
|
||
];
|
||
}
|
||
|
||
/**
|
||
* Prepare amount
|
||
*
|
||
* @param $amount int
|
||
* @return int
|
||
*/
|
||
function _commerce_rbkmoney_prepare_amount($order_wrapper)
|
||
{
|
||
$amount = $order_wrapper->commerce_order_total->amount->value();
|
||
if ($amount < 0) {
|
||
drupal_set_message(t('Requested amount less than allowed'), 'error');
|
||
drupal_goto('cart');
|
||
}
|
||
return $amount;
|
||
}
|
||
|
||
function _commerce_rbkmoney_prepare_currency($order_wrapper)
|
||
{
|
||
return $order_wrapper->commerce_order_total->currency_code->value();
|
||
}
|
||
|
||
function _commerce_rbkmoney_send($url = '', $headers = [], $data = '', $type = '')
|
||
{
|
||
$request = [
|
||
'url' => $url,
|
||
'method' => HTTP_METHOD_POST,
|
||
'body' => $data,
|
||
'headers' => $headers,
|
||
];
|
||
|
||
$curl = curl_init($url);
|
||
curl_setopt($curl, CURLOPT_POST, TRUE);
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
|
||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||
|
||
$body = curl_exec($curl);
|
||
$info = curl_getinfo($curl);
|
||
$curl_errno = curl_errno($curl);
|
||
|
||
$response['http_code'] = $info['http_code'];
|
||
$response['body'] = $body;
|
||
$response['error'] = $curl_errno;
|
||
|
||
$logs = [
|
||
'request' => $request,
|
||
'response' => $response,
|
||
];
|
||
|
||
_commerce_rbkmoney_logger($type, "<pre>%logs</pre>", ['%logs' => var_export($logs, TRUE)]);
|
||
curl_close($curl);
|
||
|
||
return $response;
|
||
}
|
||
|
||
function _commerce_rbkmoney_prepare_api_url($path = '', $query_params = [])
|
||
{
|
||
$url = rtrim(API_URL, '/') . '/' . $path;
|
||
if (!empty($query_params)) {
|
||
$url .= '?' . http_build_query($query_params);
|
||
}
|
||
|
||
return $url;
|
||
}
|
||
|
||
function _commerce_rbkmoney_logger($type, $message, $variables = [])
|
||
{
|
||
if (variable_get('commerce_rbkmoney_log', 1)) {
|
||
watchdog(MODULE_NAME . '_' . $type, $message, $variables);
|
||
}
|
||
}
|