Ручная установка модуля на битрикс, на примере "Долями"
16.12.2021
У Битрикса существует богатый каталог расширений, но поставить их можно только если активна лицензия.
Также стоит учитывать, если лицензии нет и CMS Bitrix не обновляется, то расширения могут не заработать на старых версиях php.
Именно так и получилось, при установке расширения "Долями".
Первая задача - получить сам модуль. Сделать это можно разными способами, я просто поставил пустой битрикс (установка Битрикса ) на тестовый домен, потом через Marketplace - Каталог решений установил нужный модуль.
Дальше скопировал его папку /bitrix/modules/dolyame.payment/lib/ на боевой сайт.
Вторым пунктом идет его установка. Переходим Marketplace - Установленные решения (/bitrix/admin/partner_modules.php ), находим нужное и нажимаем на кнопку "Установить", была тут:
И все бы хорошо, но модуль не заработал, причина в том, что он рассчитан на php 7.4+, пришлось его даунгрейднуть... хорошо, достаточно было отредактировать всего один файл (bitrix/modules/dolyame.payment/lib/Client.php )
Измененная версия:
<?php
namespace Dolyame\Payment;
class Client
{
protected $url = 'https://partner.dolyame.ru/v1/orders/';
protected $login = '';
protected $password = '';
protected $certPath = '';
protected $keyPath = '';
public function __construct($login, $password) {
$this->login = $login;
$this->password = $password;
}
public function setCertPath($certPath)
{
$this->certPath = $certPath;
}
public function setKeyPath($keyPath)
{
$this->keyPath = $keyPath;
}
public function generateCorrelationId()
{
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
public function create($data, $correlationId = NULL )
{
return $this->execute('create', $data, 'POST', $correlationId);
}
public function cancel($orderId, $correlationId = '')
{
$orderId = self::prepareOrderId($orderId);
return $this->execute($orderId.'/cancel', [], 'POST', $correlationId);
}
public function commit($orderId, $data, $correlationId = '')
{
$orderId = self::prepareOrderId($orderId);
return $this->execute($orderId.'/commit', $data, 'POST', $correlationId);
}
public function info($orderId, $correlationId = '')
{
$orderId = self::prepareOrderId($orderId);
return $this->execute($orderId.'/info', [], 'GET', $correlationId);
}
public function refund($orderId, $data, $correlationId = '')
{
$orderId = self::prepareOrderId($orderId);
return $this->execute($orderId.'/refund', $data, 'POST', $correlationId);
}
protected function execute($action, $data, $method, $correlationId)
{
if($correlationId === '') {
$correlationId = $this->generateCorrelationId();
}
$correlationId = $this->generateCorrelationId();
$headers = [
"Content-Type: application/json",
"X-Correlation-ID: $correlationId",
"Authorization: Basic ".base64_encode("{$this->login}:{$this->password}")
];
$responseHeaders = '';
if (!function_exists("curl_init")) {
throw new \Exception("Curl error");
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url.$action);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$responseHeaders) {
$responseHeaders .= $header;
return strlen($header);
});
if ($this->certPath) {
if (!file_exists($this->certPath)) {
throw new \Exception('Cert path did\'t exist:'.$this->certPath);
}
if (!file_exists($this->keyPath)) {
throw new \Exception('Key path did\'t exist:'.$this->keyPath);
}
if (!is_readable($this->certPath)) {
throw new \Exception('Can\'t read cert file:'.$this->certPath);
}
if (!is_readable($this->keyPath)) {
throw new \Exception('Can\'t read key file:'.$this->keyPath);
}
curl_setopt($ch, CURLOPT_SSLCERT, $this->certPath);
curl_setopt($ch, CURLOPT_SSLKEY, $this->keyPath);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if (!empty($data) || $method == 'POST') {
$encodedData = $this->encode($data);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedData);
}
$out = curl_exec($ch);
$curlError = curl_error($ch);
if ($curlError) {
throw new \Exception($curlError);
}
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$response = json_decode($out, true);
/* file_put_contents(__DIR__.'/out',
$code
."\n-----------1\n" . print_r($data, TRUE)
."\n-----------2\n" . print_r($response, TRUE)
."\n-----------3\n" . print_r($headers, TRUE)
);*/
if ($code == 200) {
return $response;
} elseif ($code == 429) {
$headers = $this->parseHeadersToArray($responseHeaders);
sleep($headers['X-Retry-After']);
return $this->execute($action, $data, $method, $correlationId);
}
$error = 'Error: ' . $code;
if (isset($response['type']) && $response['type'] == 'error') {
$error .= ' ' . $response['description'];
}
if (isset($response['message'])) {
$error .= ' '.$response['message'];
}
if (!empty($response['details'])) {
$list = array_map(
function($key, $value){return "$key - $value";},
array_keys($response['details']),
array_values($response['details'])
);
$error .= ': '.implode($list);;
}
if (!$response) {
$error .= $out;
}
throw new \Exception($error, $code);
}
protected function parseHeadersToArray($rawHeaders)
{
$lines = explode("\r\n", $rawHeaders);
$headers = [];
foreach($lines as $line) {
if (strpos($line, ':') === false ){
continue;
}
list($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
return $headers;
}
protected function encode($data)
{
if (is_string($data)) {
return $data;
}
$result = json_encode($data);
$error = json_last_error();
if ($error != JSON_ERROR_NONE) {
throw new \Exception('JSON Error: ' . json_last_error_msg());
}
return $result;
}
public static function prepareOrderId($orderId)
{
$orderId = str_replace(['/','#','?','|',' '], ['-'], $orderId);
$orderId = preg_replace("#\p{Cyrillic}#u", "", $orderId);
return $orderId;
}
}
Пометки: долями bitrix ручная установка модуля