mirror of
https://github.com/valitydev/rbkmoney-cms-wp-e-commerce.git
synced 2024-11-06 02:25:21 +00:00
ITS-28: update module
This commit is contained in:
parent
81b0bf3634
commit
49556b8edc
@ -2,7 +2,7 @@
|
||||
|
||||
Платежный плагин RBKmoney для Wordpress + WP e-Commerce
|
||||
|
||||
Проверено на Wordpress 4.3.2, WP e-Commerce 3.12.0
|
||||
Проверено на `Wordpress 4.3.2`, `WP e-Commerce 3.12.0`
|
||||
|
||||
### Установка и настройка модуля
|
||||
|
||||
|
@ -31,16 +31,27 @@ function gateway_rbkmoney_payment($separator, $sessionid)
|
||||
// e.g. RUB
|
||||
$currency = WPSC_Countries::get_currency_code(get_option('currency_type'));
|
||||
|
||||
$form_company_name = '';
|
||||
if(!empty(trim(get_option('rbkmoney_payment_form_company_name')))) {
|
||||
$form_company_name = 'data-name="' . trim(get_option('rbkmoney_payment_form_company_name')).'"';
|
||||
$company_name = '';
|
||||
if (!empty(trim(get_option('rbkmoney_payment_form_company_name')))) {
|
||||
$company_name = 'data-name="' . trim(get_option('rbkmoney_payment_form_company_name')) . '"';
|
||||
}
|
||||
|
||||
$form_path_logo = '';
|
||||
if(!empty(trim(get_option('rbkmoney_payment_form_company_name')))) {
|
||||
$form_path_logo = 'data-logo="' . trim(get_option('rbkmoney_payment_form_path_logo')).'"';
|
||||
$company_logo = '';
|
||||
if (!empty(trim(get_option('rbkmoney_payment_form_company_name')))) {
|
||||
$company_logo = 'data-logo="' . trim(get_option('rbkmoney_payment_form_path_logo')) . '"';
|
||||
}
|
||||
|
||||
$button_label = '';
|
||||
if (!empty(trim(get_option('rbkmoney_payment_form_button_label')))) {
|
||||
$button_label = 'data-label="' . trim(get_option('rbkmoney_payment_form_button_label')) . '"';
|
||||
}
|
||||
|
||||
$description = '';
|
||||
if (!empty(trim(get_option('rbkmoney_payment_form_description')))) {
|
||||
$description = 'data-description="' . trim(get_option('rbkmoney_payment_form_description')) . '"';
|
||||
}
|
||||
|
||||
|
||||
$amount = number_format($purchase_log[0]['totalprice'], 2, '', '');
|
||||
$params = array(
|
||||
'shop_id' => trim(get_option('rbkmoney_payment_shop_id')),
|
||||
@ -62,17 +73,22 @@ function gateway_rbkmoney_payment($separator, $sessionid)
|
||||
exit();
|
||||
}
|
||||
|
||||
$output = '<html><body><script src="https://checkout.rbk.money/payframe/payframe.js" class="rbkmoney-checkout"
|
||||
$output = '<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<form action="' . home_url('/?rbkmoney_payment_results') . '" method="' . HTTP_METHOD_POST . '">
|
||||
<script src="https://checkout.rbk.money/checkout.js" class="rbkmoney-checkout"
|
||||
data-invoice-id="' . $invoice_id . '"
|
||||
data-invoice-access-token="' . $invoice_access_token . '"
|
||||
data-endpoint-success="' . home_url('/?rbkmoney_payment_results') . '"
|
||||
data-endpoint-failed="' . home_url('/?rbkmoney_payment_results') . '"
|
||||
data-amount="' . $purchase_log[0]['totalprice'] . '"
|
||||
data-currency="' . $currency . '"
|
||||
' . $form_company_name . '
|
||||
' . $form_path_logo . '
|
||||
' . $company_name . '
|
||||
' . $company_logo . '
|
||||
' . $button_label . '
|
||||
' . $description . '
|
||||
>
|
||||
</script></body></html>';
|
||||
</script>
|
||||
</form></body></html>';
|
||||
|
||||
echo $output;
|
||||
exit();
|
||||
@ -88,75 +104,99 @@ function nzshpcrt_rbkmoney_payment_callback()
|
||||
|
||||
if (isset($_GET['rbkmoney_payment_callback'])) {
|
||||
|
||||
if(empty($_SERVER[RBKmoneyPayment::SIGNATURE])) {
|
||||
if (empty($_SERVER[RBKmoneyPaymentVerification::SIGNATURE])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
'Отсутствует сигнатура'
|
||||
'Webhook notification signature missing'
|
||||
);
|
||||
}
|
||||
|
||||
$params_signature = RBKmoneyPaymentVerification::get_parameters_content_signature($_SERVER[RBKmoneyPaymentVerification::SIGNATURE]);
|
||||
if (empty($params_signature[RBKmoneyPaymentVerification::SIGNATURE_ALG])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
'Missing required parameter ' . RBKmoneyPaymentVerification::SIGNATURE_ALG
|
||||
);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (empty($params_signature[RBKmoneyPaymentVerification::SIGNATURE_DIGEST])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
'Missing required parameter ' . RBKmoneyPaymentVerification::SIGNATURE_DIGEST
|
||||
);
|
||||
exit();
|
||||
}
|
||||
|
||||
$content = file_get_contents('php://input');
|
||||
|
||||
$required_fields = [
|
||||
RBKmoneyPayment::SHOP_ID,
|
||||
RBKmoneyPayment::INVOICE_ID,
|
||||
RBKmoneyPayment::PAYMENT_ID,
|
||||
RBKmoneyPayment::AMOUNT,
|
||||
RBKmoneyPayment::CURRENCY,
|
||||
RBKmoneyPayment::CREATED_AT,
|
||||
RBKmoneyPayment::METADATA,
|
||||
RBKmoneyPayment::STATUS,
|
||||
RBKmoneyPayment::EVENT_TYPE,
|
||||
];
|
||||
$data = json_decode($content, TRUE);
|
||||
foreach ($required_fields as $field) {
|
||||
if (empty($data[$field])) {
|
||||
http_response_code(RBKmoneyPayment::HTTP_CODE_BAD_REQUEST);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$current_shop_id = trim(get_option('rbkmoney_payment_shop_id'));
|
||||
if($current_shop_id != $data[RBKmoneyPayment::SHOP_ID]) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::SHOP_ID . ' не совпадает с указанным в настройках магазина'
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($data[RBKmoneyPayment::METADATA][RBKmoneyPayment::ORDER_ID])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::ORDER_ID . ' не обнаружен в ' . RBKmoneyPayment::METADATA
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($data[RBKmoneyPayment::METADATA][RBKmoneyPayment::SESSION_ID])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::SESSION_ID . ' не обнаружен в ' . RBKmoneyPayment::METADATA
|
||||
);
|
||||
}
|
||||
|
||||
$signature = base64_decode($_SERVER[RBKmoneyPayment::SIGNATURE], TRUE);
|
||||
$signature = RBKmoneyPaymentVerification::urlsafe_b64decode($params_signature[RBKmoneyPaymentVerification::SIGNATURE_DIGEST]);
|
||||
if (!RBKmoneyPaymentVerification::verification_signature($content, $signature, trim(get_option('rbkmoney_payment_callback_public_key')))) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
'Сигнатура не совпадает'
|
||||
'Webhook notification signature mismatch'
|
||||
);
|
||||
}
|
||||
|
||||
$purchase_log_sql = $wpdb->prepare( "SELECT * FROM `".WPSC_TABLE_PURCHASE_LOGS."` WHERE `id`= %s AND `sessionid`= %s LIMIT 1",
|
||||
$data[RBKmoneyPayment::METADATA][RBKmoneyPayment::ORDER_ID],
|
||||
$data[RBKmoneyPayment::METADATA][RBKmoneyPayment::SESSION_ID]
|
||||
);
|
||||
$purchase_log = $wpdb->get_results($purchase_log_sql, ARRAY_A);
|
||||
if(empty($purchase_log)) {
|
||||
$invoice = 'invoice';
|
||||
$eventType = 'eventType';
|
||||
|
||||
$required_fields = [$invoice, $eventType];
|
||||
$data = json_decode($content, TRUE);
|
||||
foreach ($required_fields as $field) {
|
||||
if (empty($data[$field])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::SESSION_ID . ' не найдена в базе данных'
|
||||
'One or more required fields are missing'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$current_shop_id = (int)trim(get_option('rbkmoney_payment_shop_id'));
|
||||
if ($current_shop_id != $data[$invoice][RBKmoneyPayment::SHOP_ID]) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::SHOP_ID . ' is missing'
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($data[$invoice][RBKmoneyPayment::METADATA][RBKmoneyPayment::ORDER_ID])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::ORDER_ID . ' is missing'
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($data[$invoice][RBKmoneyPayment::METADATA][RBKmoneyPayment::SESSION_ID])) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
RBKmoneyPayment::SESSION_ID . ' is missing'
|
||||
);
|
||||
}
|
||||
|
||||
$purchase_log_sql = $wpdb->prepare("SELECT * FROM `" . WPSC_TABLE_PURCHASE_LOGS . "` WHERE `id`= %s AND `sessionid`= %s LIMIT 1",
|
||||
$data[$invoice][RBKmoneyPayment::METADATA][RBKmoneyPayment::ORDER_ID],
|
||||
$data[$invoice][RBKmoneyPayment::METADATA][RBKmoneyPayment::SESSION_ID]
|
||||
);
|
||||
$purchase_log = $wpdb->get_results($purchase_log_sql, ARRAY_A);
|
||||
if (empty($purchase_log)) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
'Purchase not found ' . $purchase_log_sql
|
||||
);
|
||||
}
|
||||
|
||||
$order_amount = number_format($purchase_log[0]['totalprice'], 2, '', '');
|
||||
$invoice_amount = $data[$invoice]['amount'];
|
||||
if ($order_amount != $invoice_amount) {
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_BAD_REQUEST,
|
||||
'Received amount vs Order amount mismatch '. $order_amount .' - ' . $invoice_amount
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$allowed_event_types = ['InvoicePaid', 'InvoiceCancelled'];
|
||||
if (in_array($data[$eventType], $allowed_event_types)) {
|
||||
|
||||
$all_statuses = array(
|
||||
'1' => 'pending',
|
||||
@ -167,26 +207,26 @@ function nzshpcrt_rbkmoney_payment_callback()
|
||||
'6' => 'rejected',
|
||||
);
|
||||
|
||||
if(in_array($purchase_log[0]['processed'], array_search('pending', $all_statuses))) {
|
||||
if ($purchase_log[0]['processed'] == array_search('pending', $all_statuses)) {
|
||||
|
||||
$processed = array_search('pending', $all_statuses);
|
||||
$details = array(
|
||||
'processed' => $processed,
|
||||
'transactid' => $data[RBKmoneyPayment::INVOICE_ID],
|
||||
'transactid' => $data[$invoice]['id'],
|
||||
'date' => time(),
|
||||
);
|
||||
$session_id = $data[RBKmoneyPayment::METADATA][RBKmoneyPayment::SESSION_ID];
|
||||
$session_id = $data[$invoice][RBKmoneyPayment::METADATA][RBKmoneyPayment::SESSION_ID];
|
||||
|
||||
switch ($data[RBKmoneyPayment::STATUS]) {
|
||||
switch ($data[$invoice]['status']) {
|
||||
case 'paid':
|
||||
$details['processed'] = array_search('ok', $all_statuses);
|
||||
wpsc_update_purchase_log_details( $session_id, $details, 'sessionid' );
|
||||
transaction_results($session_id, false, $data[RBKmoneyPayment::INVOICE_ID]);
|
||||
wpsc_update_purchase_log_details($session_id, $details, 'sessionid');
|
||||
transaction_results($session_id, false, $data[$invoice]['id']);
|
||||
break;
|
||||
case 'cancelled':
|
||||
$details['processed'] = array_search('closed', $all_statuses);
|
||||
wpsc_update_purchase_log_details( $session_id, $details, 'sessionid' );
|
||||
transaction_results($session_id, false, $data[RBKmoneyPayment::INVOICE_ID]);
|
||||
wpsc_update_purchase_log_details($session_id, $details, 'sessionid');
|
||||
transaction_results($session_id, false, $data[$invoice]['id']);
|
||||
break;
|
||||
default:
|
||||
// The default action is not needed if a status has come that does not interest us
|
||||
@ -194,7 +234,7 @@ function nzshpcrt_rbkmoney_payment_callback()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
_rbkmoney_payment_response_with_code_and_message(
|
||||
RBKmoneyPayment::HTTP_CODE_OK,
|
||||
'OK'
|
||||
@ -239,7 +279,8 @@ function submit_rbkmoney_payment()
|
||||
$text_fields = array(
|
||||
'rbkmoney_payment_shop_id',
|
||||
'rbkmoney_payment_form_path_logo',
|
||||
'rbkmoney_payment_form_company_name',
|
||||
'rbkmoney_payment_form_button_label',
|
||||
'rbkmoney_payment_form_description',
|
||||
);
|
||||
_rbkmoney_payment_update_options($text_fields, 'text');
|
||||
|
||||
@ -304,6 +345,22 @@ function form_rbkmoney_payment()
|
||||
" . __('Your company name for payment form', 'wp-e-commerce') . "
|
||||
</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>" . __('Button label in payment form', 'wp-e-commerce') . "</td>
|
||||
<td>
|
||||
<input type='text' size='60' value='" . trim(get_option('rbkmoney_payment_form_button_label')) . "' name='rbkmoney_payment_form_button_label' />
|
||||
<p class='description'>
|
||||
" . __('Your button label for payment form', 'wp-e-commerce') . "
|
||||
</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>" . __('Description in payment form', 'wp-e-commerce') . "</td>
|
||||
<td>
|
||||
<input type='text' size='60' value='" . trim(get_option('rbkmoney_payment_form_description')) . "' name='rbkmoney_payment_form_description' />
|
||||
<p class='description'>
|
||||
" . __('Your description for payment form', 'wp-e-commerce') . "
|
||||
</p>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>" . __('Private key', 'wp-e-commerce') . "</td>
|
||||
<td>
|
||||
|
@ -27,15 +27,8 @@ class RBKmoneyPayment
|
||||
/**
|
||||
* Constants for Callback
|
||||
*/
|
||||
const SHOP_ID = 'shop_id';
|
||||
const INVOICE_ID = 'invoice_id';
|
||||
const PAYMENT_ID = 'payment_id';
|
||||
const AMOUNT = 'amount';
|
||||
const CURRENCY = 'currency';
|
||||
const CREATED_AT = 'created_at';
|
||||
const SHOP_ID = 'shopID';
|
||||
const METADATA = 'metadata';
|
||||
const STATUS = 'status';
|
||||
const SIGNATURE = 'HTTP_X_SIGNATURE';
|
||||
const ORDER_ID = 'order_id';
|
||||
const SESSION_ID = 'session_id';
|
||||
const EVENT_TYPE = 'event_type';
|
||||
@ -260,29 +253,32 @@ class RBKmoneyPayment
|
||||
'description',
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'shopID' => (int)$this->getShopId(),
|
||||
'amount' => (int)$this->getAmount(),
|
||||
'metadata' => $this->prepare_metadata($this->getOrderId(), $this->getSessionId()),
|
||||
'dueDate' => $this->prepare_due_date(),
|
||||
'currency' => $this->getCurrency(),
|
||||
'product' => $this->getProduct(),
|
||||
'description' => $this->getDescription(),
|
||||
];
|
||||
|
||||
$this->validate();
|
||||
$url = $this->prepare_api_url('processing/invoices');
|
||||
$headers = $this->headers();
|
||||
$response = $this->send($url, static::HTTP_METHOD_POST, $headers, json_encode($data, true));
|
||||
$response_decode = json_decode($response['body'], true);
|
||||
$invoice_id = !empty($response_decode['id']) ? $response_decode['id'] : '';
|
||||
return $invoice_id;
|
||||
}
|
||||
|
||||
private function headers() {
|
||||
$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' => (int)$this->amount,
|
||||
'metadata' => $this->prepare_metadata($this->order_id, $this->session_id),
|
||||
'dueDate' => $this->prepare_due_date(),
|
||||
'currency' => $this->currency,
|
||||
'product' => $this->product,
|
||||
'description' => $this->description,
|
||||
];
|
||||
|
||||
|
||||
$this->validate();
|
||||
$url = $this->prepare_api_url('processing/invoices');
|
||||
$response = $this->send($url, static::HTTP_METHOD_POST, $headers, json_encode($data, true));
|
||||
$response_decode = json_decode($response['body'], true);
|
||||
$invoice_id = !empty($response_decode['id']) ? $response_decode['id'] : '';
|
||||
return $invoice_id;
|
||||
return $headers;
|
||||
}
|
||||
|
||||
public function create_access_token($invoice_id)
|
||||
@ -290,13 +286,9 @@ class RBKmoneyPayment
|
||||
if (empty($invoice_id)) {
|
||||
throw new Exception('Не передан обязательный параметр 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');
|
||||
$headers = $this->headers();
|
||||
$response = $this->send($url, static::HTTP_METHOD_POST, $headers);
|
||||
|
||||
if ($response['http_code'] != static::HTTP_CODE_CREATED) {
|
||||
@ -313,16 +305,14 @@ class RBKmoneyPayment
|
||||
throw new Exception('Не передан обязательный параметр url');
|
||||
}
|
||||
|
||||
$allowed_methods = [static::HTTP_METHOD_POST, static::HTTP_METHOD_GET];
|
||||
$allowed_methods = [static::HTTP_METHOD_POST];
|
||||
if (!in_array($method, $allowed_methods)) {
|
||||
throw new Exception('Неподдерживаемый метод ' . $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);
|
||||
|
@ -10,6 +10,11 @@ class RBKmoneyPaymentVerification
|
||||
const OPENSSL_VERIFY_SIGNATURE_IS_INCORRECT = 0;
|
||||
const OPENSSL_VERIFY_ERROR = -1;
|
||||
|
||||
const SIGNATURE = 'HTTP_CONTENT_SIGNATURE';
|
||||
const SIGNATURE_ALG = 'alg';
|
||||
const SIGNATURE_DIGEST = 'digest';
|
||||
const SIGNATURE_PATTERN = "|alg=(\S+);\sdigest=(.*)|i";
|
||||
|
||||
public static function verification_signature($data = '', $signature = '', $public_key = '')
|
||||
{
|
||||
if (empty($data) || empty($signature) || empty($public_key)) {
|
||||
@ -23,4 +28,29 @@ class RBKmoneyPaymentVerification
|
||||
return ($verify == static::OPENSSL_VERIFY_SIGNATURE_IS_CORRECT);
|
||||
}
|
||||
|
||||
public static function urlsafe_b64decode($string)
|
||||
{
|
||||
$data = str_replace(array('-', '_'), array('+', '/'), $string);
|
||||
$mod4 = strlen($data) % 4;
|
||||
if ($mod4) {
|
||||
$data .= substr('====', $mod4);
|
||||
}
|
||||
return base64_decode($data);
|
||||
}
|
||||
|
||||
public static function urlsafe_b64encode($string)
|
||||
{
|
||||
$data = base64_encode($string);
|
||||
return str_replace(array('+', '/'), array('-', '_'), $data);
|
||||
}
|
||||
|
||||
public static function get_parameters_content_signature($content_signature)
|
||||
{
|
||||
preg_match_all(static::SIGNATURE_PATTERN, $content_signature, $matches, PREG_PATTERN_ORDER);
|
||||
$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;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user