update module (#2)

This commit is contained in:
Anatoly Cherkasov 2018-07-10 11:47:27 +03:00 committed by GitHub
parent 6ad22314bc
commit e5b9d9ad97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 100 additions and 95 deletions

View File

@ -1,15 +1,69 @@
# rbkmoney-cms-magento # rbkmoney-cms-magento
### Инструкция по установке Пожалуйста, обязательно делайте бекапы!
Платежный плагин RBKmoney для **Magento**
Модуль разрабатывался и тестировался на **Magento 1.9.1.0**
#### Требования
- PHP 5.4 (минимум)
- OpenSSL - 1.0.2k-fips (минимум)
- Curl
### Установка и настройка модуля
- Скопировать содержимое `app` в соответствующую папку `app/` - Скопировать содержимое `app` в соответствующую папку `app/`
- Установленный модуль заработает сразу после его настройки в админке: - Установленный модуль заработает сразу после его настройки в админке:
``` ```
"Система - Конфигурация - Продажи - Методы оплаты" "Система - Конфигурация" (System - Configuration)"
(System - Configuration - Sales - Payment Methods)
``` ```
- Параметры для заполнения можно получить на сайте платёжной системы [RBKmoney](https://dashboard.rbk.money) ![Plugin system](images/plugin_system.png)
- В качестве URL для уведомления о смене статуса инвойса в личном кабинете указать:
``` ```
http{s}://{your-site}/rbkmoney/payment/notification "Продажи - Методы оплаты" (Sales - Payment Methods)
``` ```
![Plugin sales](images/plugin_sales.png)
#### Для начала приема платежей на Вашем сайте осталось совсем немного
![Plugin settings](images/plugin_settings.png)
Настройте плагин в соответствии с данными из [личного кабинета RBKmoney](https://dashboard.rbk.money).
`Shop ID` - идентификатор магазина из RBKmoney. Скопируйте его в Личном кабинете RBKmoney в разделе Детали магазина, поле Идентификатор;
`Private key` - ключ для доступа к API. Скопируйте его в Личном кабинете RBKmoney в разделе API Ключ
`Callback public key` - ключ для обработки уведомлений о смене статуса
- Заходим в личный кабинет RBKmoney: Создать Webhook;
- Вставляем в поле URL вида `http{s}://{your-site}/rbkmoney/payment/notification`, скопированного из `Notification URL`
- Выбираем Типы событий `InvoicePaid` и `Invoice Canсelled`;
- после создания Webhook-а копируем Публичный ключ после нажатия Показать детали;
- скопированный ключ вставляем в поле `Публичный ключ` на странице настроек модуля;
- Сохраните изменения и проведите тестовый платеж
В настройках модуля можно включить или отключить логирование `Debug on/off`
С результатом логирования можно ознакомиться по пути `/var/log/rbkmoney.log` в корне сайта
### Нашли ошибку или у вас есть предложение по улучшению модуля?
Пишите нам `support@rbkmoney.com` При обращении необходимо:
- Указать наименование CMS и компонента магазина, а также их версии
- Указать версию платежного модуля (доступна на странице Управление пакетами)
- Описать проблему или предложение
- Приложить снимок экрана (для большей информативности)

View File

@ -9,7 +9,7 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
* Payment form * Payment form
*/ */
const PAYMENT_FORM_URL = 'https://checkout.rbk.money/checkout.js'; const PAYMENT_FORM_URL = 'https://checkout.rbk.money/checkout.js';
const API_URL = 'https://api.rbk.money/v1/'; const API_URL = 'https://api.rbk.money/v2/';
/** /**
* Create invoice settings * Create invoice settings
@ -29,7 +29,6 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
*/ */
const SETTINGS_SHOP_ID = 'shop_id'; const SETTINGS_SHOP_ID = 'shop_id';
const SETTINGS_PAYMENT_FORM_LOGO = 'payment_form_logo';
const SETTINGS_PAYMENT_FORM_COMPANY_NAME = 'payment_form_company_name'; const SETTINGS_PAYMENT_FORM_COMPANY_NAME = 'payment_form_company_name';
const SETTINGS_PAYMENT_FORM_BUTTON_LABEL = 'payment_form_button_label'; const SETTINGS_PAYMENT_FORM_BUTTON_LABEL = 'payment_form_button_label';
const SETTINGS_PAYMENT_FORM_DESCRIPTION = 'payment_form_description'; const SETTINGS_PAYMENT_FORM_DESCRIPTION = 'payment_form_description';
@ -43,7 +42,7 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
public function getShopId() public function getShopId()
{ {
return (int)Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_SHOP_ID); return trim(Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_SHOP_ID));
} }
public function getPrivateKey() public function getPrivateKey()
@ -56,11 +55,6 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
return trim(Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_CALLBACK_PUBLIC_KEY)); return trim(Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_CALLBACK_PUBLIC_KEY));
} }
public function getPaymentFormLogo()
{
return trim(Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_PAYMENT_FORM_LOGO));
}
public function getPaymentFormCompanyName() public function getPaymentFormCompanyName()
{ {
return trim(strip_tags(Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_PAYMENT_FORM_COMPANY_NAME))); return trim(strip_tags(Mage::getStoreConfig(static::COMMON_PATH . static::SETTINGS_PAYMENT_FORM_COMPANY_NAME)));
@ -96,29 +90,6 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
return Mage::getUrl('checkout/onepage/error', array('_secure' => false)); return Mage::getUrl('checkout/onepage/error', array('_secure' => false));
} }
/**
* Create invoice access token
*
* @param $invoice_id
*
* @return string
* @throws Exception
*/
public function createInvoiceAccessToken($invoice_id)
{
$url = $this->_prepareApiUrl('processing/invoices/' . $invoice_id . '/access_tokens');
$response = $this->_send($url, $this->_getHeaders(), '', 'access_tokens');
if ($response['http_code'] != static::HTTP_CODE_CREATED) {
throw new Exception('An error occurred while creating Invoice Access Token');
}
$response_decode = json_decode($response['body'], true);
$access_token = !empty($response_decode['payload']) ? $response_decode['payload'] : '';
return $access_token;
}
/** /**
* Create invoice * Create invoice
@ -141,7 +112,7 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
]; ];
$url = $this->_prepareApiUrl('processing/invoices'); $url = $this->_prepareApiUrl('processing/invoices');
$response = $this->_send($url, $this->_getHeaders(), json_encode($data), 'init_invoice'); $response = $this->_send($url, $this->_getHeaders(), json_encode($data));
if ($response['http_code'] != static::HTTP_CODE_CREATED) { if ($response['http_code'] != static::HTTP_CODE_CREATED) {
$message = 'An error occurred while creating invoice'; $message = 'An error occurred while creating invoice';
@ -149,9 +120,7 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
} }
$response_decode = json_decode($response['body'], true); $response_decode = json_decode($response['body'], true);
$invoice_id = !empty($response_decode['id']) ? $response_decode['id'] : ''; return $response_decode;
return $invoice_id;
} }
/** /**
@ -278,7 +247,8 @@ class RBKmoney_Payform_Helper_Data extends Mage_Core_Helper_Data
public function log($message, $logs = array(), $level = Zend_Log::INFO, $fileName = "rbkmoney.log") public function log($message, $logs = array(), $level = Zend_Log::INFO, $fileName = "rbkmoney.log")
{ {
if (!empty($this->getDebug())) { $debug = $this->getDebug();
if (!empty($debug)) {
Mage::log($message . ' ' . print_r($logs, true), $level, $fileName); Mage::log($message . ' ' . print_r($logs, true), $level, $fileName);
} }
} }

View File

@ -1,11 +1,6 @@
<?php <?php
/**
* Created by IntelliJ IDEA.
* User: avcherkasov
* Date: 20/04/2017
* Time: 13:10
*/
class RBKmoney_Payform_PaymentController extends Mage_Core_Controller_Front_Action class RBKmoney_Payform_PaymentController extends Mage_Core_Controller_Front_Action
{ {
@ -13,9 +8,7 @@ class RBKmoney_Payform_PaymentController extends Mage_Core_Controller_Front_Acti
* Constants for Callback * Constants for Callback
*/ */
const SIGNATURE = 'HTTP_CONTENT_SIGNATURE'; const SIGNATURE = 'HTTP_CONTENT_SIGNATURE';
const SIGNATURE_ALG = 'alg'; const SIGNATURE_PATTERN = "/alg=(\S+);\sdigest=/";
const SIGNATURE_DIGEST = 'digest';
const SIGNATURE_PATTERN = "|alg=(\S+);\sdigest=(.*)|i";
const EVENT_TYPE = 'eventType'; const EVENT_TYPE = 'eventType';
@ -65,19 +58,16 @@ class RBKmoney_Payform_PaymentController extends Mage_Core_Controller_Front_Acti
} }
$logs['signature'] = $_SERVER[static::SIGNATURE]; $logs['signature'] = $_SERVER[static::SIGNATURE];
$params_signature = $this->getParametersContentSignature($_SERVER[static::SIGNATURE]); $signature = $this->getSignatureFromHeader($_SERVER[static::SIGNATURE]);
if (empty($params_signature[static::SIGNATURE_ALG])) { $logs['signature_from_header'] = $signature;
$message = 'Missing required parameter ' . static::SIGNATURE_ALG; if (empty($signature)) {
$message = 'Signature is missing';
static::outputWithExit($message, $logs); static::outputWithExit($message, $logs);
} }
if (empty($params_signature[static::SIGNATURE_DIGEST])) { $signatureDecode = $this->urlSafeB64decode($signature);
$message = 'Missing required parameter ' . static::SIGNATURE_DIGEST; $publicKey = $payform->getCallbackPublicKey();
static::outputWithExit($message, $logs); if (!$this->verificationSignature($content, $signatureDecode, $publicKey)) {
}
$signature = $this->urlSafeB64decode($params_signature[static::SIGNATURE_DIGEST]);
if (!$this->verificationSignature($content, $signature, $payform->getCallbackPublicKey())) {
$message = 'Webhook notification signature mismatch'; $message = 'Webhook notification signature mismatch';
static::outputWithExit($message, $logs); static::outputWithExit($message, $logs);
} }
@ -93,7 +83,7 @@ class RBKmoney_Payform_PaymentController extends Mage_Core_Controller_Front_Acti
} }
} }
$current_shop_id = (int)$payform->getShopId(); $current_shop_id = $payform->getShopId();
if ($data[static::INVOICE][static::INVOICE_SHOP_ID] != $current_shop_id) { if ($data[static::INVOICE][static::INVOICE_SHOP_ID] != $current_shop_id) {
$message = static::INVOICE_SHOP_ID . ' is missing'; $message = static::INVOICE_SHOP_ID . ' is missing';
static::outputWithExit($message, $logs); static::outputWithExit($message, $logs);
@ -145,21 +135,12 @@ class RBKmoney_Payform_PaymentController extends Mage_Core_Controller_Front_Acti
private function urlSafeB64decode($string) private function urlSafeB64decode($string)
{ {
$data = str_replace(array('-', '_'), array('+', '/'), $string); return base64_decode(strtr($string, '-_,', '+/='));
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
} }
private function getParametersContentSignature($content_signature) private function getSignatureFromHeader($content_signature)
{ {
preg_match_all(static::SIGNATURE_PATTERN, $content_signature, $matches, PREG_PATTERN_ORDER); return preg_replace(static::SIGNATURE_PATTERN, '', $content_signature);
$params = array();
$params[static::SIGNATURE_ALG] = !empty($matches[1][0]) ? $matches[1][0] : '';
$params[static::SIGNATURE_DIGEST] = !empty($matches[2][0]) ? $matches[2][0] : '';
return $params;
} }
/** /**

View File

@ -43,8 +43,7 @@
<title>RBKmoney</title> <title>RBKmoney</title>
<allowspecific>0</allowspecific> <allowspecific>0</allowspecific>
<payment_action>sale</payment_action> <payment_action>sale</payment_action>
<shop_id>1</shop_id> <shop_id>TEST</shop_id>
<payment_form_logo></payment_form_logo>
<payment_form_company_name></payment_form_company_name> <payment_form_company_name></payment_form_company_name>
<payment_form_button_label></payment_form_button_label> <payment_form_button_label></payment_form_button_label>
<payment_form_description></payment_form_description> <payment_form_description></payment_form_description>

View File

@ -14,7 +14,7 @@
<frontend_class>complex</frontend_class> <frontend_class>complex</frontend_class>
<frontend_model>payform/adminhtml_system_config_fieldset_group</frontend_model> <frontend_model>payform/adminhtml_system_config_fieldset_group</frontend_model>
<comment>Process payments using your own internet merchant account.</comment> <comment>Process payments using your own internet merchant account.</comment>
<help_url>https://rbkmoney.github.io/docs/</help_url> <help_url>https://developer.rbk.money/docs/</help_url>
<fields> <fields>
<title translate="label"> <title translate="label">
<label>Title</label> <label>Title</label>
@ -92,14 +92,6 @@
<show_in_store>0</show_in_store> <show_in_store>0</show_in_store>
<sort_order>8</sort_order> <sort_order>8</sort_order>
</payment_form_css_button> </payment_form_css_button>
<payment_form_logo translate="label">
<label>Logo in payment form:</label>
<frontend_type>text</frontend_type>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>0</show_in_store>
<sort_order>9</sort_order>
</payment_form_logo>
<payment_form_company_name translate="label"> <payment_form_company_name translate="label">
<label>Company name in payment form:</label> <label>Company name in payment form:</label>
<frontend_type>text</frontend_type> <frontend_type>text</frontend_type>

View File

@ -7,23 +7,33 @@ $order->loadByIncrementId($orderId);
/*** @var RBKmoney_Payform_Helper_Data $data */ /*** @var RBKmoney_Payform_Helper_Data $data */
$data = Mage::helper("payform"); $data = Mage::helper("payform");
$dataLogo = !empty($data->getPaymentFormLogo()) ? 'data-logo="' . $data->getPaymentFormLogo() . '"' : ''; $paymentFormCompanyName = $data->getPaymentFormCompanyName();
$companyName = !empty($data->getPaymentFormCompanyName()) ? 'data-name="' . $data->getPaymentFormCompanyName() . '"' : ''; $companyName = !empty($paymentFormCompanyName) ? 'data-name="' . $paymentFormCompanyName . '"' : '';
$buttonLabel = !empty($data->getPaymentFormButtonLabel()) ? 'data-label="' . $data->getPaymentFormButtonLabel() . '"' : '';
$description = !empty($data->getPaymentFormDescription()) ? 'data-description="' . $data->getPaymentFormDescription() . '"' : '';
$style = !empty($data->getPaymentFormCssButton()) ? '<style>' . $data->getPaymentFormCssButton() . '</style>' : ''; $paymentFormButtonLabel = $data->getPaymentFormButtonLabel();
$buttonLabel = !empty($paymentFormButtonLabel) ? 'data-label="' . $paymentFormButtonLabel . '"' : '';
$paymentFormDescription = $data->getPaymentFormDescription();
$description = !empty($paymentFormDescription) ? 'data-description="' . $paymentFormDescription . '"' : '';
$paymentFormCssButton = $data->getPaymentFormCssButton();
$style = !empty($paymentFormCssButton) ? '<style>' . $paymentFormCssButton . '</style>' : '';
try { try {
if(empty($_SESSION['order']) || $_SESSION['order']['id'] != $orderId) { if(empty($_SESSION['order']) || $_SESSION['order']['id'] != $orderId) {
$invoice_id = $data->createInvoice($order); $response = $data->createInvoice($order);
$invoice_id = $response["invoice"]["id"];
$invoice_access_token = $response["invoiceAccessToken"]["payload"];
$_SESSION['order']['id'] = $orderId; $_SESSION['order']['id'] = $orderId;
$_SESSION['order']['invoice_id'] = $invoice_id; $_SESSION['order']['invoice_id'] = $invoice_id;
$_SESSION['order']['invoiceAccessToken'] = $invoice_access_token;
} else { } else {
$invoice_id = $_SESSION['order']['invoice_id']; $invoice_id = $_SESSION['order']['invoice_id'];
$invoice_access_token = $_SESSION['order']['invoiceAccessToken'];
} }
$invoice_access_token = $data->createInvoiceAccessToken($invoice_id);
} catch (Exception $ex) { } catch (Exception $ex) {
die($ex->getMessage()); die($ex->getMessage());
} }
@ -34,9 +44,8 @@ try {
<form action="<?php echo $data->getSuccessUrl(); ?>" method="POST"> <form action="<?php echo $data->getSuccessUrl(); ?>" method="POST">
<script src="<?php echo $data::PAYMENT_FORM_URL; ?>" class="rbkmoney-checkout" <script src="<?php echo $data::PAYMENT_FORM_URL; ?>" class="rbkmoney-checkout"
data-invoice-id="<?php echo $invoice_id; ?>" data-invoice-id="<?php echo $invoice_id; ?>"
data-invoice-access-token="<?php echo $invoice_access_token; ?>" data-invoice-access-token="<?php echo $invoice_access_token; ?>"
<?php echo $dataLogo; ?>
<?php echo $companyName; ?> <?php echo $companyName; ?>
<?php echo $buttonLabel; ?> <?php echo $buttonLabel; ?>
<?php echo $description; ?> <?php echo $description; ?>

BIN
images/plugin_sales.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
images/plugin_settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
images/plugin_system.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB