ITS-23: uploaded the module (#1)

* ITS-23: uploaded the module

* ITS-23: changed static pages

* ITS-23: changed url for redirection

* ITS-23: include sdk

* ITS-23: post review fix

* ITS-23: modified README.md

* ITS-23: fix amount
This commit is contained in:
Anatoly Cherkasov 2017-03-24 19:07:06 +03:00 committed by GitHub
parent c9f7492740
commit 657b929fff
32 changed files with 1157 additions and 1 deletions

53
.gitignore vendored Normal file
View File

@ -0,0 +1,53 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.DS_Store
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
# Target folder
target

View File

@ -1 +1,29 @@
# rbkmoney-cms-bitrix
# rbkmoney-cms-bitrix
### Установка и настройка модуля
1) Скопируйте папку `rbkmoney_payment` и все ее содержимое на ваш сервер в `\bitrix\modules\`
2) В "Управление модулями" найдите модуль `«RBKmoney (rbkmoney_payment)` и установите его.
![Установка модуля](images/managing.png)
1) Перейдите в «Магазин» -> «Платежные системы» и нажмите на кнопку «Добавить платежную систему»
1) Заполните данные в открывшемся окне:
![Настройка модуля](images/settings.png)
В качестве `Callback Url`-а для обработки уведомления от платежной системы в личном кабинете укажите URL:
```
https://<your-bitrix-site>/personal/order/rbkmoney_payment/notification.php
```
Чтобы уведомления от платежной системы доходили, необходимо будет добавить публичный ключ, который можно получить в личном кабинете и добавить его в настройках модуля в поле "Публичный ключ для авторизации уведомлений о статусе оплаты"
3) Заполните оставшиеся поля и нажмите кнопку «Применить»:
В поля «Публичный ключ для авторизации уведомлений о статусе оплаты», «Приватный ключ для проведения оплаты», «Номер магазина в системе RBKmoney» заполните данными из Личного Кабинета Мерчанта https://dashboard.rbk.money
В поле «Моя компания» укажите название компании, которое будет отображаться в платежной форме.
Все запросы и ответы логируются, с ними можно ознакомиться в разделе `Журнал событий`

BIN
images/managing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
images/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

View File

@ -0,0 +1 @@
<?php

View File

@ -0,0 +1,85 @@
<?
IncludeModuleLangFile(__FILE__);
/**
* RBKmoney Payment Module
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
*
* @version 1.0
* @author RBKmoney
* @copyright Copyright (c) 2017 RBKmoney
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*
* EXTENSION INFORMATION
*
* 1C-Bitrix 17.0
* RBKmoney DOCS https://rbkmoney.github.io/docs/
*
*/
Class rbkmoney_payment extends CModule
{
var $MODULE_ID = 'rbkmoney_payment';
var $MODULE_VERSION;
var $MODULE_VERSION_DATE;
var $MODULE_NAME;
var $MODULE_DESCRIPTION;
function __construct()
{
$arModuleVersion = array();
include(dirname(__FILE__) . '/version.php');
if (is_array($arModuleVersion) && array_key_exists('VERSION', $arModuleVersion)) {
$this->MODULE_VERSION = trim($arModuleVersion['VERSION']);
$this->MODULE_VERSION_DATE = trim($arModuleVersion['VERSION_DATE']);
}
$this->MODULE_NAME = trim(GetMessage('RBKMONEY_MODULE_NAME'));
$this->MODULE_DESCRIPTION = trim(GetMessage('RBKMONEY_MODULE_DESC'));
$this->PARTNER_NAME = trim(GetMessage('RBKMONEY_PARTNER_NAME'));
$this->PARTNER_URI = trim(GetMessage('RBKMONEY_PARTNER_URI'));
}
function InstallFiles()
{
CopyDirFiles(
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/notifications',
$_SERVER['DOCUMENT_ROOT'] . '/personal/order/' . $this->MODULE_ID
);
CopyDirFiles(
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/' . $this->MODULE_ID . '/install/sale_payment/' . $this->MODULE_ID,
$_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/sale/payment/' . $this->MODULE_ID,
true, true
);
return true;
}
function UnInstallFiles()
{
DeleteDirFilesEx('bitrix/modules/sale/payment/' . $this->MODULE_ID);
DeleteDirFilesEx('personal/order/' . $this->MODULE_ID);
return true;
}
function DoInstall()
{
global $DOCUMENT_ROOT, $APPLICATION;
$this->InstallFiles();
RegisterModule($this->MODULE_ID);
$APPLICATION->IncludeAdminFile(GetMessage('RBKMONEY_INSTALL_TITLE'), $DOCUMENT_ROOT . '/bitrix/modules/' . $this->MODULE_ID . '/install/step.php');
return true;
}
function DoUninstall()
{
global $DOCUMENT_ROOT, $APPLICATION;
$this->UnInstallFiles();
UnRegisterModule($this->MODULE_ID);
$APPLICATION->IncludeAdminFile(GetMessage('RBKMONEY_UNINSTALL_TITLE'), $DOCUMENT_ROOT . '/bitrix/modules/' . $this->MODULE_ID . '/install/unstep.php');
return true;
}
}

View File

@ -0,0 +1,12 @@
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/header.php');
$APPLICATION->SetTitle('Title');
?>
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/sale/payment/rbkmoney_payment/failed.php');
?>
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/footer.php');
?>

View File

@ -0,0 +1,3 @@
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/sale/payment/rbkmoney_payment/failed_redirect.php');
?>

View File

@ -0,0 +1,3 @@
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/sale/payment/rbkmoney_payment/notification.php');
?>

View File

@ -0,0 +1,12 @@
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/header.php');
$APPLICATION->SetTitle('Title');
?>
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/sale/payment/rbkmoney_payment/success.php');
?>
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/footer.php');
?>

View File

@ -0,0 +1,3 @@
<?
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/sale/payment/rbkmoney_payment/success_redirect.php');
?>

View File

@ -0,0 +1,59 @@
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();?>
<?php
include(GetLangFileName(dirname(__FILE__)."/", "/.description.php"));
$psTitle = "RBKmoney";
$psDescription = "<a href=\"https://rbkmoney.github.io/docs/\" target=\"_blank\">https://rbkmoney.github.io/docs</a>";
$arPSCorrespondence = array(
"SHOULD_PAY" => array(
"NAME" => GetMessage("SALE_RBKMONEY_SHOULD_PAY"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_SHOULD_PAY"),
"VALUE" => "SHOULD_PAY",
"TYPE" => "ORDER"
),
"CURRENCY" => array(
"NAME" => GetMessage("SALE_RBKMONEY_CURRENCY"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_CURRENCY"),
"VALUE" => "CURRENCY",
"TYPE" => "ORDER"
),
"ORDER_ID" => array(
"NAME" => GetMessage("SALE_RBKMONEY_ORDER_ID"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_ORDER_ID"),
"VALUE" => "ID",
"TYPE" => "ORDER"
),
"FORM_PATH_IMG_LOGO" => array(
"NAME" => GetMessage("SALE_RBKMONEY_FORM_PATH_IMG_LOGO"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_FORM_COMPANY_NAME"),
"VALUE" => "https://checkout.rbk.money/checkout/images/logo.png",
"TYPE" => ""
),
"FORM_COMPANY_NAME" => array(
"NAME" => GetMessage("SALE_RBKMONEY_FORM_COMPANY_NAME"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_FORM_PATH_IMG_LOGO"),
"VALUE" => "",
"TYPE" => ""
),
"MERCHANT_CALLBACK_PUBLIC_KEY" => array(
"NAME" => GetMessage("SALE_RBKMONEY_MERCHANT_CALLBACK_PUBLIC_KEY"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_MERCHANT_CALLBACK_PUBLIC_KEY"),
"VALUE" => "",
"TYPE" => ""
),
"MERCHANT_PRIVATE_KEY" => array(
"NAME" => GetMessage("SALE_RBKMONEY_MERCHANT_PRIVATE_KEY"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_MERCHANT_PRIVATE_KEY"),
"VALUE" => "",
"TYPE" => ""
),
"SHOP_ID" => array(
"NAME" => GetMessage("SALE_RBKMONEY_SHOP_ID"),
"DESCR" => GetMessage("SALE_RBKMONEY_DESCRIPTION_SHOP_ID"),
"VALUE" => "0000000",
"TYPE" => ""
),
);
?>

View File

@ -0,0 +1,28 @@
<?php
global $MESS;
$MESS["SALE_RBKMONEY_SHOULD_PAY"] = "Amount to be paid";
$MESS["SALE_RBKMONEY_DESCRIPTION_SHOULD_PAY"] = "";
$MESS["SALE_RBKMONEY_ORDER_ID"] = "Order ID";
$MESS["SALE_RBKMONEY_DESCRIPTION_ORDER_ID"] = "Order ID from your Internet store";
$MESS["SALE_RBKMONEY_FORM_PATH_IMG_LOGO"] = "The path to the image of the store logo displayed in the payment form";
$MESS["SALE_RBKMONEY_DESCRIPTION_FORM_PATH_IMG_LOGO"] = "";
$MESS["SALE_RBKMONEY_FORM_COMPANY_NAME"] = "Company name displayed in the payment form";
$MESS["SALE_RBKMONEY_DESCRIPTION_FORM_COMPANY_NAME"] = "";
$MESS["SALE_RBKMONEY_MERCHANT_PRIVATE_KEY"] = "Private key for payment";
$MESS["SALE_RBKMONEY_DESCRIPTION_MERCHANT_PRIVATE_KEY"] = "";
$MESS["SALE_RBKMONEY_MERCHANT_CALLBACK_PUBLIC_KEY"] = "Public key to authorize payment status notifications";
$MESS["SALE_RBKMONEY_DESCRIPTION_MERCHANT_CALLBACK_PUBLIC_KEY"] = "";
$MESS["SALE_RBKMONEY_SHOP_ID"] = "Shop ID in RBK Money";
$MESS["SALE_RBKMONEY_DESCRIPTION_SHOP_ID"] = "";
$MESS["SALE_RBKMONEY_CURRENCY"] = "Currency";
$MESS["SALE_RBKMONEY_DESCRIPTION_CURRENCY"] = "";
?>

View File

@ -0,0 +1,14 @@
<?php
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
CModule::IncludeModule('sale');
$APPLICATION->SetPageProperty("title", "Информация о заказе");
$APPLICATION->SetPageProperty("NOT_SHOW_NAV_CHAIN", "Y");
$APPLICATION->SetTitle("Оплата заказа");
?>
Платеж не прошел, попробуйте еще раз
<?php require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>

View File

@ -0,0 +1,6 @@
<?php
include(dirname(__FILE__) . "/sdk/rbkmoney_autoload.php");
header('Location: /personal/order/rbkmoney_payment/failed.php', true, RBKmoney::HTTP_CODE_MOVED_PERMANENTLY);
exit();
?>

View File

@ -0,0 +1,3 @@
<?php
include(dirname(__FILE__) . '/result_rec.php');
?>

View File

@ -0,0 +1,65 @@
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); ?>
<?
include(dirname(__FILE__) . "/sdk/rbkmoney_autoload.php");
$order_id = CSalePaySystemAction::GetParamValue("ORDER_ID");
$shop_id = CSalePaySystemAction::GetParamValue("SHOP_ID");
$success_url = RBKmoneyUrlHelper::getBaseUrlWithSlash() . 'personal/order/rbkmoney_payment/success.php';
$failed_url = RBKmoneyUrlHelper::getBaseUrlWithSlash() . 'personal/order/rbkmoney_payment/failed.php';
$amount = number_format(CSalePaySystemAction::GetParamValue("SHOULD_PAY"), 2, '.', '');
$currency = trim(CSalePaySystemAction::GetParamValue("CURRENCY"));
$params = array(
'shop_id' => $shop_id,
'currency' => $currency,
'product' => $order_id,
'description' => 'Order ID ' . $order_id,
'amount' => $amount,
'order_id' => $order_id,
'success_url' => $success_url,
'failed_url' => $failed_url,
'merchant_private_key' => trim(CSalePaySystemAction::GetParamValue("MERCHANT_PRIVATE_KEY")),
);
$invoiceId = '';
$invoice_access_token = '';
try {
$rbk_api = new RBKmoney($params);
if (empty($order['PAY_VOUCHER_NUM'])) {
$response_create_invoice = $rbk_api->create_invoice();
$create_invoice_encode = json_decode($response_create_invoice['body'], true);
$invoiceId = !empty($create_invoice_encode['id']) ? $create_invoice_encode['id'] : '';
CSaleOrder::Update($order_id, Array(
'PAY_VOUCHER_NUM' => $invoiceId,
'PAY_VOUCHER_DATE' => $GLOBALS["SALE_INPUT_PARAMS"]["ORDER"]["DATE_INSERT"]
));
} else {
$invoiceId = $order['PAY_VOUCHER_NUM'];
}
$invoice_access_token = $rbk_api->create_access_token($invoiceId);
} catch (Exception $ex) {
$logs = [
"code" => $ex->getCode(),
"message" => $ex->getMessage(),
];
RBKmoneyLogger::loggerError("init_invoice_exception", $logs);
}
?>
<script src="https://checkout.rbk.money/payframe/payframe.js" class="rbkmoney-checkout"
data-invoice-id="<?= trim($invoiceId); ?>"
data-invoice-access-token="<?= trim($invoice_access_token); ?>"
data-endpoint-success="<?= trim($success_url) ?>"
data-endpoint-failed="<?= trim($failed_url) ?>"
data-amount="<?= $amount ?>"
data-currency="<?= $currency ?>"
data-name="<?= trim(CSalePaySystemAction::GetParamValue("FORM_COMPANY_NAME")) ?>"
data-logo="<?= trim(CSalePaySystemAction::GetParamValue("FORM_PATH_IMG_LOGO")) ?>"
>
</script>

View File

@ -0,0 +1,115 @@
<?php
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/bx_root.php");
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
CModule::IncludeModule('sale');
?>
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); ?>
<?php
include(dirname(__FILE__) . "/sdk/rbkmoney_autoload.php");
$body = file_get_contents('php://input');
$logs = array(
'request' => array(
'method' => 'POST',
'data' => $body,
),
);
$item_id = 'notification';
RBKmoneyLogger::loggerInfo($item_id, $logs);
if (empty($_SERVER[RBKmoney::SIGNATURE])) {
$logs['error'] = array(
'message' => 'Сигнатура отсутствует',
);
RBKmoneyLogger::loggerError('notification', $logs);
http_response_code(RBKmoney::HTTP_CODE_BAD_REQUEST);
exit();
}
$required_fields = array(
RBKmoney::INVOICE_ID,
RBKmoney::PAYMENT_ID,
RBKmoney::AMOUNT,
RBKmoney::CURRENCY,
RBKmoney::CREATED_AT,
RBKmoney::METADATA,
RBKmoney::STATUS
);
$data = json_decode($body, TRUE);
foreach ($required_fields as $field) {
if (empty($data[$field])) {
$logs['error'] = array(
'message' => 'Отсутствует обязательное поле: ' . $field,
);
RBKmoneyLogger::loggerError($item_id, $logs);
http_response_code(RBKmoney::HTTP_CODE_BAD_REQUEST);
exit();
}
}
if (empty($data[RBKmoney::METADATA][RBKmoney::ORDER_ID])) {
$logs['error'] = array(
'message' => 'Отсутствует номер заказа',
);
RBKmoneyLogger::loggerError($item_id, $logs);
http_response_code(RBKmoney::HTTP_CODE_BAD_REQUEST);
exit();
}
$signature = base64_decode($_SERVER[RBKmoney::SIGNATURE]);
$public_key = CSalePaySystemAction::GetParamValue("SALE_RBKMONEY_MERCHANT_CALLBACK_PUBLIC_KEY");
if (!RBKmoneyVerification::signature($body, $signature, $public_key)) {
$logs['error'] = array(
'message' => 'Сигнатура не совпадает',
);
RBKmoneyLogger::loggerError($item_id, $logs);
http_response_code(RBKmoney::HTTP_CODE_BAD_REQUEST);
exit();
}
$orderId = $data[RBKmoney::METADATA][RBKmoney::ORDER_ID];
if (!($arOrder = CSaleOrder::GetByID($orderId))) {
$logs['error'] = array(
'message' => 'Заказ ' . $orderId . ' не найден',
);
RBKmoneyLogger::loggerError($item_id, $logs);
http_response_code(RBKmoney::HTTP_CODE_BAD_REQUEST);
exit();
}
if ($arOrder["PAYED"] == "Y") {
$logs['error'] = array(
'message' => 'Заказ ' . $orderId . ' уже оплачен',
);
RBKmoneyLogger::loggerError($item_id, $logs);
http_response_code(RBKmoney::HTTP_CODE_BAD_REQUEST);
exit();
}
if ($arOrder["PAYED"] != "Y" && $data[RBKmoney::STATUS] == "paid") {
$logs['order_payment'] = "Заказ оплачен";
CSaleOrder::PayOrder($arOrder["ID"], "Y");
}
$arFields = array(
"PS_STATUS" => "Y",
"PS_STATUS_CODE" => $data[RBKmoney::STATUS],
"PS_STATUS_DESCRIPTION" => $body,
"PS_STATUS_MESSAGE" => 'ok',
"PS_SUM" => $data[RBKmoney::AMOUNT],
"PS_CURRENCY" => $data[RBKmoney::CURRENCY],
"PS_RESPONSE_DATE" => Date(CDatabase::DateFormatToPHP(CLang::GetDateFormat("FULL", LANG))),
);
$logs['status_fields'] = $arFields;
RBKmoneyLogger::loggerInfo($item_id, $logs);
CSaleOrder::Update($arOrder["ID"], $arFields);
?>

View File

@ -0,0 +1,28 @@
<?php
global $MESS;
$MESS["SALE_RBKMONEY_SHOULD_PAY"] = "Сумма к оплате";
$MESS["SALE_RBKMONEY_DESCRIPTION_SHOULD_PAY"] = "";
$MESS["SALE_RBKMONEY_ORDER_ID"] = "Номер заказа";
$MESS["SALE_RBKMONEY_DESCRIPTION_ORDER_ID"] = "Номер заказа в вашем Интернет-магазине";
$MESS["SALE_RBKMONEY_FORM_PATH_IMG_LOGO"] = "Путь до изображения логотипа магазина отображаемого в платежной форме";
$MESS["SALE_RBKMONEY_DESCRIPTION_FORM_PATH_IMG_LOGO"] = "";
$MESS["SALE_RBKMONEY_FORM_COMPANY_NAME"] = "Название компании отображаемое в платежной форме";
$MESS["SALE_RBKMONEY_DESCRIPTION_FORM_COMPANY_NAME"] = "";
$MESS["SALE_RBKMONEY_MERCHANT_PRIVATE_KEY"] = "Приватный ключ для проведения оплаты";
$MESS["SALE_RBKMONEY_DESCRIPTION_MERCHANT_PRIVATE_KEY"] = "";
$MESS["SALE_RBKMONEY_MERCHANT_CALLBACK_PUBLIC_KEY"] = "Публичный ключ для авторизации уведомлений о статусе оплаты";
$MESS["SALE_RBKMONEY_DESCRIPTION_MERCHANT_CALLBACK_PUBLIC_KEY"] = "";
$MESS["SALE_RBKMONEY_SHOP_ID"] = "Номер магазина в системе RBKmoney";
$MESS["SALE_RBKMONEY_DESCRIPTION_SHOP_ID"] = "";
$MESS["SALE_RBKMONEY_CURRENCY"] = "Валюта оплаты";
$MESS["SALE_RBKMONEY_DESCRIPTION_CURRENCY"] = "";
?>

View File

@ -0,0 +1,446 @@
<?php
/**
* Class RBKmoney
*/
class RBKmoney
{
/**
* HTTP METHOD
*/
const HTTP_METHOD_POST = 'POST';
const HTTP_METHOD_GET = 'GET';
/**
* HTTP CODE
*/
const HTTP_CODE_OK = 200;
const HTTP_CODE_CREATED = 201;
const HTTP_CODE_MOVED_PERMANENTLY = 301;
const HTTP_CODE_BAD_REQUEST = 400;
const HTTP_CODE_INTERNAL_SERVER_ERROR = 500;
/**
* Create invoice settings
*/
const CREATE_INVOICE_TEMPLATE_DUE_DATE = 'Y-m-d\TH:i:s\Z';
const CREATE_INVOICE_DUE_DATE = '+1 days';
/**
* Constants for Callback
*/
const INVOICE_ID = 'invoice_id';
const PAYMENT_ID = 'payment_id';
const AMOUNT = 'amount';
const CURRENCY = 'currency';
const CREATED_AT = 'created_at';
const METADATA = 'metadata';
const STATUS = 'status';
const SIGNATURE = 'HTTP_X_SIGNATURE';
const ORDER_ID = 'order_id';
private $api_url = 'https://api.rbk.money/v1/';
private $merchant_private_key = '';
private $shop_id = '';
private $currency = '';
private $product = '';
private $description = '';
private $amount = 0;
private $order_id;
protected $errors = array();
protected $requiredFields = array();
/**
* @return string
*/
public function getApiUrl()
{
return $this->api_url;
}
/**
* @param string $api_url
*/
public function setApiUrl($api_url)
{
if (filter_var($api_url, FILTER_VALIDATE_URL) === false) {
$this->setErrors($api_url . ' is not a valid URL');
}
$this->api_url = $api_url;
}
/**
* @return string
*/
public function getMerchantPrivateKey()
{
return $this->merchant_private_key;
}
/**
* @param string $merchant_private_key
*/
public function setMerchantPrivateKey($merchant_private_key)
{
$this->merchant_private_key = $merchant_private_key;
}
/**
* @return string
*/
public function getShopId()
{
return $this->shop_id;
}
/**
* @param string $shop_id
*/
public function setShopId($shop_id)
{
$this->shop_id = $shop_id;
}
/**
* @return string
*/
public function getCurrency()
{
return $this->currency;
}
/**
* @param string $currency
*/
public function setCurrency($currency)
{
$this->currency = $currency;
}
/**
* @return string
*/
public function getProduct()
{
return $this->product;
}
/**
* @param string $product
*/
public function setProduct($product)
{
$this->product = $product;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* @return int
*/
public function getAmount()
{
return $this->amount;
}
/**
* @param $amount
* @throws RBKmoneyException
*/
public function setAmount($amount)
{
if(!is_integer($amount)) {
throw new RBKmoneyException($amount . ' no a integer');
}
$this->amount = $amount;
}
/**
* @return mixed
*/
public function getOrderId()
{
return $this->order_id;
}
/**
* @param mixed $order_id
*/
public function setOrderId($order_id)
{
$this->order_id = $order_id;
}
/**
* Получаем данные об ошибках
* @return array
*/
private function getErrors()
{
return $this->errors;
}
/**
* Сохраняем данные об ошибках
* @param array $errors
*/
private function setErrors($errors)
{
$this->errors[] = $errors;
}
/**
* Очистка стека ошибок
*/
private function clearErrors()
{
$this->errors = array();
}
/**
* Возвращает массив обязательных полей
* @return array
*/
public function getRequiredFields()
{
return $this->requiredFields;
}
public function setRequiredFields($requiredFields)
{
if (!is_array($requiredFields) || empty($requiredFields)) {
$this->setErrors('Отсутствуют обязательные поля');
}
$this->requiredFields = $requiredFields;
}
public function __construct(array $params = array())
{
if (!empty($params)) {
$this->bind($params);
}
}
private function toUpper($pockets)
{
return ucfirst(str_replace(['_', '-'], '', $pockets[1]));
}
private function getMethodName($name, $prefix = 'get')
{
$key = preg_replace_callback('{([_|-]\w)}s', array(__CLASS__, 'toUpper'), $name);
return $prefix . ucfirst($key);
}
private function bind(array $params)
{
foreach ($params as $name => $value) {
$method = $this->getMethodName($name, 'set');
if (!empty($value) && method_exists($this, $method)) {
$this->$method($value);
}
}
}
private function checkRequiredFields()
{
$required_fields = $this->getRequiredFields();
foreach ($required_fields as $field) {
$method = $this->getMethodName($field);
if (method_exists($this, $method)) {
$value = $this->$method();
if (empty($value)) $this->setErrors('<b>' . $field . '</b> is required');
} else {
$this->setErrors($field . ' method not found');
}
}
}
/**
* Prepare due date
*
* @return string
*/
private function prepare_due_date()
{
date_default_timezone_set('UTC');
return date(static::CREATE_INVOICE_TEMPLATE_DUE_DATE, strtotime(static::CREATE_INVOICE_DUE_DATE));
}
/**
* Prepare metadata
*
* @param $order_id
* @return array
*/
private function prepare_metadata($order_id)
{
return [
'cms' => 'bitrix',
'cms_version' => '17.0.0',
'module' => 'rbkmoney_payment',
'order_id' => $order_id,
];
}
/**
* Prepare amount (e.g. 124.24 -> 12424)
*
* @param $amount int
* @return int
*/
private function prepare_amount($amount)
{
return $amount * 100;
}
private function prepare_api_url($path = '', $query_params = [])
{
$url = rtrim($this->api_url, '/') . '/' . $path;
if (!empty($query_params)) {
$url .= '?' . http_build_query($query_params);
}
return $url;
}
public function create_invoice()
{
$this->setRequiredFields([
'merchant_private_key',
'shop_id',
'amount',
'order_id',
'currency',
'product',
'description',
]);
$headers = [];
$headers[] = 'X-Request-ID: ' . uniqid();
$headers[] = 'Authorization: Bearer ' . $this->merchant_private_key;
$headers[] = 'Content-type: application/json; charset=utf-8';
$headers[] = 'Accept: application/json';
$data = [
'shopID' => (int)$this->shop_id,
'amount' => $this->prepare_amount($this->amount),
'metadata' => $this->prepare_metadata($this->order_id),
'dueDate' => $this->prepare_due_date(),
'currency' => $this->currency,
'product' => $this->product,
'description' => $this->description,
];
$this->validate();
$url = $this->prepare_api_url('processing/invoices');
return $this->send($url, static::HTTP_METHOD_POST, $headers, json_encode($data, true), 'init_invoice');
}
public function create_access_token($invoice_id)
{
if (empty($invoice_id)) {
throw new RBKmoneyException('Не передан обязательный параметр invoice_id');
}
$headers = [];
$headers[] = 'X-Request-ID: ' . uniqid();
$headers[] = 'Authorization: Bearer ' . $this->merchant_private_key;
$headers[] = 'Content-type: application/json; charset=utf-8';
$headers[] = 'Accept: application/json';
$url = $this->prepare_api_url('processing/invoices/' . $invoice_id . '/access_tokens');
$response = $this->send($url, static::HTTP_METHOD_POST, $headers, '', 'access_tokens');
if ($response['http_code'] != static::HTTP_CODE_CREATED) {
throw new RBKmoneyException('Возникла ошибка при создании токена для инвойса');
}
$response_decode = json_decode($response['body'], true);
$access_token = !empty($response_decode['payload']) ? $response_decode['payload'] : '';
return $access_token;
}
private function send($url, $method, $headers = [], $data = '', $type = '')
{
$logs = array(
'request' => array(
'url' => $url,
'method' => $method,
'headers' => $headers,
'data' => $data,
),
);
RBKmoneyLogger::loggerInfo($type . ': request', $logs);
if (empty($url)) {
throw new RBKmoneyException('Не передан обязательный параметр url');
}
$allowed_methods = [static::HTTP_METHOD_POST, static::HTTP_METHOD_GET];
if (!in_array($method, $allowed_methods)) {
RBKmoneyLogger::loggerError(__CLASS__, $logs);
throw new RBKmoneyException('Unsupported method ' . $method);
}
$curl = curl_init($url);
if ($method == static::HTTP_METHOD_POST) {
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['response'] = $response;
RBKmoneyLogger::loggerInfo($type . ': response', $logs);
curl_close($curl);
return $response;
}
private function validate() {
$this->checkRequiredFields();
if (count($this->getErrors()) > 0) {
$errors = 'Errors found: ' . implode(', ', $this->getErrors());
RBKmoneyLogger::loggerError(__CLASS__, $errors);
throw new RBKmoneyException($errors);
}
$this->clearErrors();
}
}

View File

@ -0,0 +1,10 @@
<?php
/**
* Class RBKmoneyException
*/
class RBKmoneyException extends Exception {
}
?>

View File

@ -0,0 +1,48 @@
<?php
class RBKmoneyLogger
{
const AUDIT_TYPE_ID = 'Платежный модуль: rbkmoney_payment';
const MODULE_ID = 'main';
const SEVERITY_ERROR = 'ERROR';
const SEVERITY_SECURITY = 'SECURITY';
const SEVERITY_WARNING = 'WARNING';
const SEVERITY_INFO = 'INFO';
const SEVERITY_DEBUG = 'DEBUG';
public static function loggerInfo($item_id, $description)
{
static::logger(
static::SEVERITY_INFO,
static::AUDIT_TYPE_ID,
static::MODULE_ID,
$item_id,
$description
);
}
public static function loggerError($item_id, $description)
{
static::logger(
static::SEVERITY_ERROR,
static::AUDIT_TYPE_ID,
static::MODULE_ID,
$item_id,
$description
);
}
public static function logger($severity, $audit_type_id, $module_id, $item_id, $description)
{
CEventLog::Add(array(
"SEVERITY" => $severity,
"AUDIT_TYPE_ID" => $audit_type_id,
"MODULE_ID" => $module_id,
"ITEM_ID" => $item_id,
"DESCRIPTION" => print_r($description, true),
));
}
}

View File

@ -0,0 +1,30 @@
<?php
/**
* Class RBKmoneyUrlHelper
*/
class RBKmoneyUrlHelper
{
public static function getCurrentSchema()
{
return ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? "https" : "http");
}
public static function getCurrentHostName()
{
return $_SERVER['HTTP_HOST'];
}
public static function getBaseUrlWithOutSlash()
{
return rtrim(static::getCurrentSchema() . '://' . static::getCurrentHostName(), '/');
}
public static function getBaseUrlWithSlash()
{
return rtrim(static::getCurrentSchema() . '://' . static::getCurrentHostName(), '/') . '/';
}
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Class RBKmoneyVerification
*/
class RBKmoneyVerification
{
/**
* Openssl verify
*/
const OPENSSL_VERIFY_SIGNATURE_IS_CORRECT = 1;
const OPENSSL_VERIFY_SIGNATURE_IS_INCORRECT = 0;
const OPENSSL_VERIFY_ERROR = -1;
public static function verification_signature($data = '', $signature = '', $public_key = '')
{
if (empty($data) || empty($signature) || empty($public_key)) {
return FALSE;
}
$public_key_id = openssl_get_publickey($public_key);
if (empty($public_key_id)) {
return FALSE;
}
$verify = openssl_verify($data, $signature, $public_key_id, OPENSSL_ALGO_SHA256);
return ($verify == static::OPENSSL_VERIFY_SIGNATURE_IS_CORRECT);
}
}
?>

View File

@ -0,0 +1,9 @@
<?php
include_once(dirname(__FILE__)."/RBKmoney.php");
include_once(dirname(__FILE__)."/RBKmoneyException.php");
include_once(dirname(__FILE__)."/RBKmoneyUrlHelper.php");
include_once(dirname(__FILE__)."/RBKmoneyVerification.php");
include_once(dirname(__FILE__)."/RBKmoneyLogger.php");
?>

View File

@ -0,0 +1,14 @@
<?php
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
CModule::IncludeModule('sale');
$APPLICATION->SetPageProperty("title", "Информация о заказе");
$APPLICATION->SetPageProperty("NOT_SHOW_NAV_CHAIN", "Y");
$APPLICATION->SetTitle("Оплата заказа");
?>
Платеж принят, заказ обрабатывается
<?php require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php"); ?>

View File

@ -0,0 +1,6 @@
<?php
include(dirname(__FILE__) . "/sdk/rbkmoney_autoload.php");
header('Location: /personal/order/rbkmoney_payment/success.php', true, RBKmoney::HTTP_CODE_MOVED_PERMANENTLY);
exit();
?>

View File

@ -0,0 +1,5 @@
<?if(!check_bitrix_sessid()) return;?>
<?
echo CAdminMessage::ShowNote(GetMessage('RBKMONEY_INSTALL_MESSAGE'));
?>

View File

@ -0,0 +1,5 @@
<?if(!check_bitrix_sessid()) return;?>
<?
echo CAdminMessage::ShowNote(GetMessage('RBKMONEY_UNINSTALL_MESSAGE'));
?>

View File

@ -0,0 +1,6 @@
<?
$arModuleVersion = array(
'VERSION' => '1.0.0',
'VERSION_DATE' => '2013-09-23 15:00:00'
);

View File

@ -0,0 +1,14 @@
<?php
$MESS['RBKMONEY_MODULE_NAME'] = 'RBKmoney';
$MESS['RBKMONEY_MODULE_DESC'] = "RBKmoney payment module for Bitrix CMS: \"Small business\", \"Business\" and \"Business web-cluster\".";
$MESS['RBKMONEY_PARTNER_NAME'] = 'RBKmoney';
$MESS['RBKMONEY_PARTNER_URI'] = 'https://rbk.money';
$MESS['RBKMONEY_INSTALL_TITLE'] = 'Installing the module '. $MESS['RBKMONEY_MODULE_NAME'];
$MESS['RBKMONEY_INSTALL_MESSAGE'] = 'Module '. $MESS['RBKMONEY_MODULE_NAME'] . ' installed';
$MESS['RBKMONEY_UNINSTALL_TITLE'] = 'Uninstalling the module '. $MESS['RBKMONEY_MODULE_NAME'];
$MESS['RBKMONEY_UNINSTALL_MESSAGE'] = 'Module '. $MESS['RBKMONEY_MODULE_NAME'] . ' was successfully removed from the system';
?>

View File

@ -0,0 +1,14 @@
<?php
$MESS['RBKMONEY_MODULE_NAME'] = 'RBKmoney';
$MESS['RBKMONEY_MODULE_DESC'] = "RBKmoney платёжный модуль для Bitrix CMS: \"Small business\", \"Business\" и \"Business web-cluster\".";
$MESS['RBKMONEY_PARTNER_NAME'] = 'RBKmoney';
$MESS['RBKMONEY_PARTNER_URI'] = 'https://rbk.money';
$MESS['RBKMONEY_INSTALL_TITLE'] = 'Установка модуля '. $MESS['RBKMONEY_MODULE_NAME'];
$MESS['RBKMONEY_INSTALL_MESSAGE'] = 'Модуль '. $MESS['RBKMONEY_MODULE_NAME'] . ' установлен';
$MESS['RBKMONEY_UNINSTALL_TITLE'] = 'Деинсталляция модуля '. $MESS['RBKMONEY_MODULE_NAME'];
$MESS['RBKMONEY_UNINSTALL_MESSAGE'] = 'Модуль '. $MESS['RBKMONEY_MODULE_NAME'] . ' успешно удален из системы';
?>