-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ITS-22: added module * ITS-22: update module * ITS-22: update README.md * ITS-22: modified README.md * ITS-22: update currency in create invoice * ITS-22: modified README.md * ITS-22: added default uc_rbkmoney_log * ITS-22: post review fix * ITS-22: added if * ITS-22: added constants * ITS-22: added link * ITS-22: rename module * ITS-22: rename module in README.md * ITS-22: update constant
- Loading branch information
1 parent
c562f33
commit 2186c3d
Showing
10 changed files
with
997 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,23 @@ | ||
# rbkmoney-cms-drupal-ubercart | ||
# Drupal uc_rbkmoney module | ||
|
||
Модуль оплаты `rbkmoney_checkout_ubercart` необходим для интеграции с сервисом [RBKmoney](http://rbk.money/) на базе CMS Drupal и компонента [Drupal ubercart](https://www.drupal.org/project/ubercart). | ||
|
||
|
||
### Требования к CMS Drupal: | ||
* версия `7.x`; | ||
* компонент `Ubercart`. Модуль тестировался на `Ubercart 7.x-3.10` | ||
|
||
|
||
### Установка и настройка | ||
|
||
С установкой и настройкой модуля можно ознакомиться в документации самого [модуля](https://www.drupal.org/sandbox/antonlva/rbkmoney_checkout_ubercart) | ||
|
||
|
||
### Нашли ошибку или у вас есть предложение по улучшению модуля? | ||
|
||
Пишите нам [email protected] | ||
При обращении необходимо: | ||
* Указать наименование CMS и компонента магазина, а также их версии | ||
* Указать версию платежного модуля (доступна в списке меню `Модули`) | ||
* Описать проблему или предложение | ||
* Приложить снимок экрана (для большей информативности) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Drupal uc_rbkmoney module | ||
|
||
Платежный модуль для Ubercart, позволяющий принимать платежи через систему RBKmoney. | ||
Модуль отправляет запрос платежа платежной системе, и обрабатывает возвращаемый ответ, меняя в соответствии с ним статус заказа. | ||
|
||
|
||
### Установка и настройка | ||
|
||
Модуль находится в папке `rbkmoney_checkout_ubercart` | ||
|
||
1. Установка. Копируем папку с модулем в каталог `/sites/all/modules` | ||
2. Включаем модуль на странице `/admin/build/modules`, раздел **Ubercart - payment** | ||
3. Настройка осуществляется по адресу `/admin/store/settings/uc_rbkmoney` | ||
1. Прописываем ShopId магазина (берем из личного кабинета) | ||
2. Копируем приватный ключ (берем из личного кабинета) | ||
3. Копируем публичный ключ для обработки уведомлений (берем из личного кабинета) | ||
4. Указать в личном кабинете callback URL для обработки уведомлений о смене статуса инвойса: https://<your-site>/rbkmoney_checkout_ubercart/callback/result | ||
|
||
Пожалуйста, обязательно делайте бекапы! |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions
138
rbkmoney_checkout_ubercart/includes/rbkmoney_checkout_ubercart_callback.pages.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<?php | ||
/** | ||
* Callback URL for RBKmoney server response | ||
* | ||
* @see https://rbkmoney.github.io/webhooks-events-api/ | ||
*/ | ||
function rbkmoney_checkout_ubercart_callback_result() | ||
{ | ||
$type = 'callback_result'; | ||
$content = file_get_contents('php://input'); | ||
_rbkmoney_checkout_ubercart_logger($type, "<pre>%logs</pre>", ['%logs' => var_export(['content' => $content], TRUE)]); | ||
|
||
if (empty($_SERVER[SIGNATURE])) { | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
_rbkmoney_checkout_ubercart_logger($type, "Webhook notification signature missing. <pre>%logs</pre>", ['%logs' => var_export(['content' => $content], TRUE)]); | ||
echo json_encode(array('message' => 'Webhook notification signature missing')); | ||
exit(); | ||
} | ||
|
||
$params_signature = _rbkmoney_checkout_ubercart_get_parameters_content_signature($_SERVER[SIGNATURE]); | ||
if (empty($params_signature[SIGNATURE_ALG])) { | ||
_rbkmoney_checkout_ubercart_logger($type, "Missing required parameter " . SIGNATURE_ALG . " signature. <pre>%logs</pre>", ['%logs' => var_export(['content' => $content], TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => 'Missing required parameter ' . SIGNATURE_ALG)); | ||
exit(); | ||
} | ||
|
||
if (empty($params_signature[SIGNATURE_DIGEST])) { | ||
_rbkmoney_checkout_ubercart_logger($type, "Missing required parameter " . SIGNATURE_DIGEST . " signature. <pre>%logs</pre>", ['%logs' => var_export(['content' => $content], TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => 'Missing required parameter ' . SIGNATURE_DIGEST)); | ||
exit(); | ||
} | ||
|
||
$signature = _rbkmoney_checkout_ubercart_urlsafe_b64decode($params_signature[SIGNATURE_DIGEST]); | ||
if (!_rbkmoney_checkout_ubercart_verification_signature($content, $signature, MERCHANT_CALLBACK_PUBLIC_KEY)) { | ||
_rbkmoney_checkout_ubercart_logger($type, "Webhook notification signature mismatch. <pre>%logs</pre>", | ||
['%logs' => var_export([ | ||
$_SERVER[SIGNATURE], | ||
$content, | ||
$signature, | ||
MERCHANT_CALLBACK_PUBLIC_KEY | ||
], TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => 'Webhook notification signature mismatch')); | ||
exit(); | ||
} | ||
|
||
$required_fields = [INVOICE, EVENT_TYPE]; | ||
$data = json_decode($content, TRUE); | ||
|
||
foreach ($required_fields as $field) { | ||
if (empty($data[$field])) { | ||
_rbkmoney_checkout_ubercart_logger($type, " One or more required fields are missing <pre>%logs</pre>", | ||
['%logs' => var_export([ | ||
'input_content' => $content, | ||
'required_fields' => $required_fields | ||
], TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => 'One or more required fields are missing')); | ||
exit(); | ||
} | ||
} | ||
|
||
$current_shop_id = (int)variable_get('uc_rbkmoney_shop_id'); | ||
if ($data[INVOICE][INVOICE_SHOP_ID] != $current_shop_id) { | ||
_rbkmoney_checkout_ubercart_logger($type, ' Webhook notification ' . INVOICE_SHOP_ID . ' mismatch<pre>%logs</pre>', ['%logs' => var_export($content, TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => INVOICE_SHOP_ID . ' is missing')); | ||
exit(); | ||
} | ||
|
||
if (empty($data[INVOICE][INVOICE_METADATA][ORDER_ID])) { | ||
_rbkmoney_checkout_ubercart_logger($type, ORDER_ID . ' is missing <pre>%logs</pre>', ['%logs' => var_export($content, TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => ORDER_ID . ' is missing')); | ||
exit(); | ||
} | ||
|
||
$order_id = $data[INVOICE][INVOICE_METADATA][ORDER_ID]; | ||
$order = uc_order_load($order_id); | ||
$order_amount = _rbkmoney_checkout_ubercart_prepare_amount($order->order_total); | ||
$invoice_amount = $data[INVOICE][INVOICE_AMOUNT]; | ||
if ($order_amount != $invoice_amount) { | ||
_rbkmoney_checkout_ubercart_logger($type, 'Received amount vs Order amount mismatch <pre>%logs</pre>', ['%logs' => var_export($content, TRUE)]); | ||
http_response_code(HTTP_CODE_BAD_REQUEST); | ||
echo json_encode(array('message' => 'Received amount vs Order amount mismatch')); | ||
exit(); | ||
} | ||
|
||
$allowed_event_types = [EVENT_TYPE_INVOICE_PAID, EVENT_TYPE_INVOICE_CANCELLED]; | ||
if (in_array($data[EVENT_TYPE], $allowed_event_types)) { | ||
$invoice_status = $data[INVOICE][INVOICE_STATUS]; | ||
_rbkmoney_checkout_ubercart_update_status_order($order_id, $invoice_status); | ||
} | ||
|
||
exit(); | ||
} | ||
|
||
function _rbkmoney_checkout_ubercart_urlsafe_b64decode($string) | ||
{ | ||
$data = str_replace(array('-', '_'), array('+', '/'), $string); | ||
$mod4 = strlen($data) % 4; | ||
if ($mod4) { | ||
$data .= substr('====', $mod4); | ||
} | ||
return base64_decode($data); | ||
} | ||
|
||
function _rbkmoney_checkout_ubercart_urlsafe_b64encode($string) | ||
{ | ||
$data = base64_encode($string); | ||
return str_replace(array('+', '/'), array('-', '_'), $data); | ||
} | ||
|
||
function _rbkmoney_checkout_ubercart_get_parameters_content_signature($content_signature) | ||
{ | ||
preg_match_all(SIGNATURE_PATTERN, $content_signature, $matches, PREG_PATTERN_ORDER); | ||
$params = array(); | ||
$params[SIGNATURE_ALG] = !empty($matches[1][0]) ? $matches[1][0] : ''; | ||
$params[SIGNATURE_DIGEST] = !empty($matches[2][0]) ? $matches[2][0] : ''; | ||
return $params; | ||
} | ||
|
||
function _rbkmoney_checkout_ubercart_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_SIGNATURE_ALG); | ||
return ($verify == OPENSSL_VERIFY_SIGNATURE_IS_CORRECT); | ||
} |
143 changes: 143 additions & 0 deletions
143
rbkmoney_checkout_ubercart/includes/rbkmoney_checkout_ubercart_settings.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
|
||
/** | ||
* Define payment statuses | ||
*/ | ||
define('UC_RBKMONEY_STATUS_FAILED', 'cancelled'); | ||
define('UC_RBKMONEY_STATUS_SUCCESS', 'paid'); | ||
|
||
define('ANONYMOUS_USER_ID', 0); | ||
|
||
/** | ||
* Module data | ||
*/ | ||
define('MODULE_NAME', 'rbkmoney_checkout_ubercart'); | ||
define('MODULE_BASE_PATH', base_path() . drupal_get_path('module', MODULE_NAME)); | ||
|
||
/** | ||
* Api URL | ||
*/ | ||
define('API_URL', 'https://api.rbk.money/v1/'); | ||
|
||
/** | ||
* Merchant settings | ||
*/ | ||
define('MERCHANT_PRIVATE_KEY', trim(variable_get('uc_rbkmoney_merchant_private_key', 'merchant_private_key'))); | ||
define('MERCHANT_CALLBACK_PUBLIC_KEY', trim(variable_get('uc_rbkmoney_merchant_callback_public_key', 'merchant_callback_public_key'))); | ||
|
||
/** | ||
* Payment form | ||
*/ | ||
define('BASE_URL', $GLOBALS['base_url']); | ||
define('PAYMENT_FORM_URL', 'https://checkout.rbk.money/checkout.js'); | ||
define('PAYMENT_FORM_SUCCESS_URL', BASE_URL . '/'.MODULE_NAME.'/success'); | ||
define('PAYMENT_FORM_PATH_IMG_LOGO', BASE_URL . MODULE_BASE_PATH . '/images/logo_default.png'); | ||
|
||
/** | ||
* Payment method logo | ||
*/ | ||
define('PAYMENT_METHOD_PATH_IMG_LOGO', MODULE_BASE_PATH . '/images/logo_rbkmoney.png'); | ||
|
||
/** | ||
* Payment form default css button | ||
*/ | ||
define('PAYMENT_FORM_DEFAULT_CSS_BUTTON', trim(variable_get('uc_rbkmoney_payform_css_button', ' | ||
button.rbkmoney-button { | ||
border: 1px solid #e4e4e4; | ||
border-bottom: 1px solid #b4b4b4; | ||
border-left-color: #d2d2d2; | ||
border-right-color: #d2d2d2; | ||
color: #2f2f2f; | ||
cursor: pointer; | ||
text-align: center; | ||
margin-top: 2px; | ||
margin-bottom: 1em; | ||
margin-right: 0.6em; | ||
padding: 4px 17px; | ||
border-radius: 15px; | ||
background: #eee; | ||
box-shadow: none; | ||
font: normal 0.929em/1.1em "Lucida Grande", "Lucida Sans Unicode", Verdana, sans-serif; | ||
} | ||
button.rbkmoney-button:hover { | ||
background: #dedede; | ||
}' | ||
))); | ||
|
||
/** | ||
* Create invoice settings | ||
*/ | ||
define('CREATE_INVOICE_TEMPLATE_DUE_DATE', 'Y-m-d\TH:i:s\Z'); | ||
define('CREATE_INVOICE_DUE_DATE', '+1 days'); | ||
|
||
/** | ||
* Constants for Callback | ||
*/ | ||
|
||
define('SIGNATURE', 'HTTP_CONTENT_SIGNATURE'); | ||
define('SIGNATURE_ALG', 'alg'); | ||
define('SIGNATURE_DIGEST', 'digest'); | ||
define('SIGNATURE_PATTERN', "|alg=(\S+);\sdigest=(.*)|i"); | ||
|
||
|
||
define('EVENT_TYPE', 'eventType'); | ||
|
||
// EVENT TYPE INVOICE | ||
define('EVENT_TYPE_INVOICE_CREATED', 'InvoiceCreated'); | ||
define('EVENT_TYPE_INVOICE_PAID', 'InvoicePaid'); | ||
define('EVENT_TYPE_INVOICE_CANCELLED', 'InvoiceCancelled'); | ||
define('EVENT_TYPE_INVOICE_FULFILLED', 'InvoiceFulfilled'); | ||
|
||
// EVENT TYPE PAYMENT | ||
define('EVENT_TYPE_PAYMENT_STARTED', 'PaymentStarted'); | ||
define('EVENT_TYPE_PAYMENT_PROCESSED', 'PaymentProcessed'); | ||
define('EVENT_TYPE_PAYMENT_CAPTURED', 'PaymentCaptured'); | ||
define('EVENT_TYPE_PAYMENT_CANCELLED', 'PaymentCancelled'); | ||
define('EVENT_TYPE_PAYMENT_FAILED', 'PaymentFailed'); | ||
|
||
|
||
define('INVOICE', 'invoice'); | ||
define('INVOICE_ID', 'id'); | ||
define('INVOICE_SHOP_ID', 'shopID'); | ||
define('INVOICE_STATUS', 'status'); | ||
define('INVOICE_DUE_DATE', 'dueDate'); | ||
define('INVOICE_AMOUNT', 'amount'); | ||
define('INVOICE_CURRENCY', 'currency'); | ||
define('INVOICE_REASON', 'reason'); | ||
define('INVOICE_METADATA', 'metadata'); | ||
|
||
define('ORDER_ID', 'order_id'); | ||
|
||
define('PAYMENT', 'payment'); | ||
define('PAYMENT_ID', 'id'); | ||
define('PAYMENT_AMOUNT', 'amount'); | ||
define('PAYMENT_CURRENCY', 'currency'); | ||
define('PAYMENT_STATUS', 'status'); | ||
|
||
/** | ||
* Api params | ||
*/ | ||
define('API_INVOICE_ID', 'invoice_id'); | ||
|
||
/** | ||
* Openssl verify | ||
*/ | ||
define('OPENSSL_VERIFY_SIGNATURE_IS_CORRECT', 1); | ||
define('OPENSSL_VERIFY_SIGNATURE_IS_INCORRECT', 0); | ||
define('OPENSSL_VERIFY_ERROR', -1); | ||
define('OPENSSL_SIGNATURE_ALG', OPENSSL_ALGO_SHA256); | ||
|
||
/** | ||
* HTTP CODE | ||
*/ | ||
define('HTTP_CODE_OK', 200); | ||
define('HTTP_CODE_CREATED', 201); | ||
define('HTTP_CODE_MOVED_PERMANENTLY', 301); | ||
define('HTTP_CODE_BAD_REQUEST', 400); | ||
define('HTTP_CODE_INTERNAL_SERVER_ERROR', 500); | ||
|
||
/** | ||
* HTTP METHOD | ||
*/ | ||
define('HTTP_METHOD_GET', 'GET'); | ||
define('HTTP_METHOD_POST', 'POST'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name = RBKmoney | ||
description = Provide RBKmoney payment gateway | ||
package = "Ubercart - payment" | ||
core = 7.x | ||
php = 5.x | ||
configure = admin/store/settings/rbkmoney_checkout_ubercart | ||
dependencies[] = uc_payment | ||
project = rbkmoney |
Oops, something went wrong.