Init
This commit is contained in:
commit
d5ed07ae40
|
|
@ -0,0 +1,310 @@
|
|||
# PSCB PHP SDK (beta)
|
||||
|
||||
- [Общая информация](#общая-информация)
|
||||
- [Требования](#требования)
|
||||
- [Описание](#описание)
|
||||
- [Структура компонента SDK](#структура-компонента-sdk)
|
||||
- [Методы работы с платежами](#методы-работы-с-платежами)
|
||||
- [Вызов платежной формы](#вызов-платежной-формы)
|
||||
- [Пример вызова платежной формы:](#пример-вызова-платежной-формы)
|
||||
- [Создание платежа СБП](#создание-платежа-сбп)
|
||||
- [Пример использования:](#пример-использования-1)
|
||||
- [Подтверждение предавторизации](#подтверждение-предавторизации)
|
||||
- [Пример использования:](#пример-использования-2)
|
||||
- [Отмена предавторизации](#отмена-предиавторизации)
|
||||
- [Пример использования:](#пример-использования-3)
|
||||
- [Возврат платежа](#возврат-платежа)
|
||||
- [Пример использования:](#пример-использования-4)
|
||||
- [Обработка нотификаций](#обработка-нотификаций)
|
||||
- [Подключение](#подключение)
|
||||
- [Примеры использования](#примеры-использования)
|
||||
- [Вопросы и ответы](#вопросы-и-ответы)
|
||||
|
||||
## Общая информация
|
||||
|
||||
Библиотека является дополнением к API интернет-эквайринга ПСКБ и позволяет интегрировать прием платежей картами и СБП в PHP-проекты с минимальными усилиями.
|
||||
|
||||
### Требования
|
||||
|
||||
PHP 8.0+
|
||||
|
||||
### Описание
|
||||
|
||||
SDK включает 2 базовых компонента, которые предназначены для следующих целей:
|
||||
|
||||
- `SDK_PayModul` – методы работы с платежами
|
||||
- `SDK_Callback` – обработка нотификаций
|
||||
|
||||
Для работы с SDK вам понадобятся:
|
||||
|
||||
- `marketPlace` – идентификатор Магазина
|
||||
- `secretKey` – секретный ключ, используемый для аутентификации
|
||||
|
||||
Параметры `marketPlace` и `secretKey` доступны в [Кабинете мерчанта](https://oos.pscb.ru/auth) в разделе "Профиль". Параметр `secretKey` отличается для тестового и боевого окружения Системы.
|
||||
|
||||
### Структура компонента SDK
|
||||
|
||||
| Файл/каталог | Описание |
|
||||
|--------------| --- |
|
||||
| `README.md` | Cодержит информацию про доступные для передачи параметры в методы класса |
|
||||
| `events` | Отображает ответы и результаты выполнения от API (путь хранения выбирается самостоятельно) |
|
||||
| `logs` | Отображает ответы и результаты выполнения от SDK (путь хранения выбирается самостоятельно) |
|
||||
| `src` | Каталог с исходными кодами SDK |
|
||||
|
||||
|
||||
## Методы работы с платежами
|
||||
|
||||
### Вызов платежной формы
|
||||
|
||||
#### Пример вызова платежной формы:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
//Подключение библиотеки
|
||||
include 'payment.class.php';
|
||||
//Основные параметры платежа
|
||||
$data = array(
|
||||
"marketPlace" => 47607,
|
||||
"secretKey" => '111111',
|
||||
"orderId" => 2000,
|
||||
"request_url"=>" https://oosdemo.pscb.ru ",
|
||||
"hold" => true // Активируем создание двухстадийного платежа картой
|
||||
);
|
||||
//Параметры для чека
|
||||
$products = array(
|
||||
array(
|
||||
"object" => 'Товар1',
|
||||
"quantity" => 1,
|
||||
"price" => 2,
|
||||
"amount" => 2
|
||||
),
|
||||
);
|
||||
//Указание путей для сохранения логов и событий
|
||||
//Вместо logs и events установите свой путь для сохранения, например /var/log
|
||||
$M = new SetWay();
|
||||
$M->SetLogsAndEvensWay('logs','events');
|
||||
//Создание экземпляра платежной формы и ее запуск
|
||||
$PayForm = new ClassPay($data);
|
||||
$PayForm->CreatePayment($products);
|
||||
?>
|
||||
```
|
||||
|
||||
### Создание платежа СБП
|
||||
|
||||
Для создания платежа через СБП используйте класс `ClassInvoicing`.
|
||||
|
||||
#### Пример использования:
|
||||
|
||||
```php
|
||||
<?php
|
||||
// ... подключение библиотеки и настройка путей для логов ...
|
||||
|
||||
$data = array(
|
||||
"marketPlace" => 47607,
|
||||
"orderId" => 6026,
|
||||
"request_url"=>"https://oosdemo.pscb.ru",
|
||||
"secretKey" => '111111',
|
||||
"sbpRedirectUrl"=>"https://your-site.com/sbp-callback" //URL - для сайтов, schema - для мобильных приложений
|
||||
);
|
||||
|
||||
$products = array(
|
||||
array(
|
||||
"object" => 'Товар1',
|
||||
"quantity" => 1,
|
||||
"price" => 2,
|
||||
"amount" => 2
|
||||
),
|
||||
);
|
||||
|
||||
$InvoicingPay = new ClassInvoicing($data);
|
||||
$result = $InvoicingPay->CreatePayment($products);
|
||||
?>
|
||||
```
|
||||
|
||||
### Подтверждение предавторизации
|
||||
|
||||
Для подтверждения двухстадийного платежа картой используйте класс `ClassConfirm`.
|
||||
|
||||
#### Пример использования:
|
||||
```php
|
||||
<?php
|
||||
// ... подключение библиотеки и настройка путей для логов ...
|
||||
|
||||
$data = array(
|
||||
"marketPlace" => 47607,
|
||||
"orderId" => 6026,
|
||||
"request_url"=>"https://oosdemo.pscb.ru",
|
||||
"secretKey" => '111111'
|
||||
);
|
||||
|
||||
$products = array(
|
||||
array(
|
||||
"object" => 'Товар1',
|
||||
"quantity" => 1,
|
||||
"price" => 2,
|
||||
"amount" => 2
|
||||
),
|
||||
);
|
||||
|
||||
$ConfirmPay = new ClassConfirm($data);
|
||||
$result = $ConfirmPay->CreatePayment($products);
|
||||
?>
|
||||
```
|
||||
|
||||
### Отмена предавторизации
|
||||
|
||||
Для отмены двухстадийного платежа картой используйте класс `ClassReject`.
|
||||
|
||||
#### Пример использования:
|
||||
```php
|
||||
<?php
|
||||
// ... подключение библиотеки и настройка путей для логов ...
|
||||
|
||||
$data = array(
|
||||
"marketPlace" => 47607,
|
||||
"orderId" => 6026,
|
||||
"request_url"=>"https://oosdemo.pscb.ru",
|
||||
"secretKey" => '111111'
|
||||
);
|
||||
|
||||
$RejectPay = new ClassReject($data);
|
||||
$result = $RejectPay->CancelPayment();
|
||||
?>
|
||||
```
|
||||
|
||||
### Возврат платежа
|
||||
|
||||
Для возврата платежа используйте класс `ClassRefund`.
|
||||
|
||||
#### Пример использования:
|
||||
```php
|
||||
<?php
|
||||
// ... подключение библиотеки и настройка путей для логов ...
|
||||
|
||||
$data = array(
|
||||
"marketPlace" => 47607,
|
||||
"orderId" => 6026,
|
||||
"request_url"=>"https://oosdemo.pscb.ru",
|
||||
"secretKey" => '111111',
|
||||
"partialRefund"=> true // Укажите false для полного возврата
|
||||
);
|
||||
|
||||
$products = array(
|
||||
array(
|
||||
"object" => 'Товар1',
|
||||
"quantity" => 1,
|
||||
"price" => 2,
|
||||
"amount" => 2
|
||||
),
|
||||
);
|
||||
|
||||
$RefundPay = new ClassRefund($data);
|
||||
$result = $RefundPay->CreatePayment($products);
|
||||
?>
|
||||
```
|
||||
|
||||
## Обработка нотификаций
|
||||
|
||||
Сценарий работы с нотификациями позволяет получать уведомления об изменении статусов платежей. Для обработки нотификаций используйте класс `CallbackClass`.
|
||||
|
||||
### Подключение
|
||||
```php
|
||||
<?php
|
||||
include 'Src/CallbackClass/CallbackClass.php';
|
||||
|
||||
$callback = new CallbackClass();
|
||||
$result = $callback->processNotification($_POST);
|
||||
?>
|
||||
```
|
||||
|
||||
### Примеры использования
|
||||
```php
|
||||
<?php
|
||||
// ... подключение библиотеки ...
|
||||
$callback = new CallbackClass();
|
||||
$notificationData = $callback->processNotification($_POST);
|
||||
|
||||
if ($notificationData['status'] == 'success') {
|
||||
// Обработка успешного платежа
|
||||
} else {
|
||||
// Обработка ошибки
|
||||
}
|
||||
?>
|
||||
```
|
||||
|
||||
## Вопросы и ответы
|
||||
|
||||
**Q: Как изменить пути для сохранения логов?**
|
||||
A: Используйте метод `SetLogsAndEvensWay` класса `SetWay`:
|
||||
```php
|
||||
$M = new SetWay();
|
||||
$M->SetLogsAndEvensWay('/custom/logs/path', '/custom/events/path');
|
||||
```
|
||||
|
||||
**Q: Как проверить корректность URL для запросов?**
|
||||
A: SDK автоматически проверяет URL на соответствие допустимым доменам: oos.pscb.ru или oosdemo.pscb.ru.
|
||||
|
||||
**Q: Как обрабатывать ошибки?**
|
||||
A: Все ошибки записываются в соответствующие log-файлы в указанной директории. Также можно анализировать возвращаемые значения методов.
|
||||
|
||||
**Q: Как настроить обратный редирект после успешной оплаты через СБП?**
|
||||
A: Используйте параметр `sbpRedirectUrl` при создании платежа:
|
||||
|
||||
```php
|
||||
$data = array(
|
||||
// ... другие параметры ...
|
||||
"sbpRedirectUrl" ="https://your-site.com/success"
|
||||
);
|
||||
```
|
||||
|
||||
**Q: Как настроить язык платежной формы?**
|
||||
A: Используйте параметр `displayLanguage`:
|
||||
```php
|
||||
$data = array(
|
||||
// ... другие параметры ...
|
||||
"displayLanguage" ="en" // Доступные значения: "ru", "en"
|
||||
);
|
||||
```
|
||||
|
||||
**Q: Как включить режим отладки?**
|
||||
A: Добавьте параметр `debug` со значением `true`:
|
||||
```php
|
||||
$data = array(
|
||||
// ... другие параметры ...
|
||||
"debug" =true
|
||||
);
|
||||
```
|
||||
|
||||
**Q: Какой формат данных требуется для позиций чека?**
|
||||
A: Каждая позиция чека должна содержать следующие поля:
|
||||
```php
|
||||
array(
|
||||
"object" ='Название товара',
|
||||
"quantity" =1, // Количество
|
||||
"price" =100.50, // Цена за единицу
|
||||
"amount" =100.50 // Общая сумма
|
||||
)
|
||||
```
|
||||
|
||||
**Q: Как обрабатывать повторные платежи с одинаковым `orderId`?**
|
||||
A: SDK автоматически проверяет уникальность `orderId`. При попытке создать платеж с уже существующим `orderId` будет возвращена ошибка.
|
||||
|
||||
**Q: Как создавать установочные платежи для сохранения реквизитов карты?**
|
||||
A: Для сохранения реквизитов карты/создания установочных рекуррентных платежей используйте параметр `recurrentable`:
|
||||
```php
|
||||
$data = array(
|
||||
// ... другие параметры ...
|
||||
"recurrentable" = true
|
||||
);
|
||||
```
|
||||
|
||||
**Q: Как получить QR-код для оплаты?**
|
||||
A: Для получения QR-кода установите параметры `requestQrCodeImage` и `requestQrCodeImageUrl` в `true`:
|
||||
```php
|
||||
$data = array(
|
||||
// ... другие параметры ...
|
||||
"requestQrCodeImage" =true,
|
||||
"requestQrCodeImageUrl" =true
|
||||
);
|
||||
```
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
include 'callbackDir/index.php';
|
||||
?>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
class CallingCallback
|
||||
{
|
||||
public $merchant_key;
|
||||
public $orderId;
|
||||
public $amount;
|
||||
public $state;
|
||||
public $marketPlace;
|
||||
public $paymentMethod;
|
||||
private $array;
|
||||
public $string;
|
||||
|
||||
public $WayLog;
|
||||
public $WayEvents;
|
||||
|
||||
public function __construct($array = '')
|
||||
{
|
||||
session_start();
|
||||
$this->WayLog = trim($_SESSION['log_way']);
|
||||
$this->WayEvents = trim($_SESSION['events_way']);
|
||||
|
||||
if (!is_array($array)) {
|
||||
file_put_contents($this->WayLog.'/callback.log',PHP_EOL.'Массив данных не был передан в конструктор', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->array = $array;
|
||||
|
||||
$this->merchant_key = $this->array['secretKey'];
|
||||
$this->orderId = $this->array["orderId"];
|
||||
}
|
||||
|
||||
function decrypt_aes128_ecb_pkcs5($encrypted, $merchant_key)
|
||||
{
|
||||
$key_md5_binary = hash("md5", $merchant_key, true);
|
||||
$decrypted = openssl_decrypt($encrypted, "AES-128-ECB", $key_md5_binary,OPENSSL_RAW_DATA);
|
||||
return $decrypted;
|
||||
}
|
||||
|
||||
public function processGetCallback($choise = true)
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST')
|
||||
{
|
||||
$encrypted_request = file_get_contents('php://input');
|
||||
$decrypted_request = $this->decrypt_aes128_ecb_pkcs5($encrypted_request, $this->merchant_key);
|
||||
|
||||
$fp = fopen($this->WayLog.'/callback.log', 'a');
|
||||
fwrite($fp, 'Содержимое пришедшее от callback: '.$decrypted_request. "\n");
|
||||
|
||||
$data_array = json_decode($decrypted_request, true);
|
||||
|
||||
//Разбор полученного содержимого
|
||||
foreach ($data_array["payments"] as $payment)
|
||||
{
|
||||
foreach ($payment as $key => $value)
|
||||
{
|
||||
$keys = ['orderId','marketPlace','amount','paymentMethod'];
|
||||
|
||||
if ((in_array($key, $keys))) {
|
||||
$ValueInsideJSON[] = $value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$this->string = (string) $this->orderId;
|
||||
|
||||
if($choise)
|
||||
{
|
||||
file_put_contents($this->WayEvents.'/CallbackPayment.json', PHP_EOL.$decrypted_request, FILE_APPEND);
|
||||
return $decrypted_request;
|
||||
}
|
||||
|
||||
if(!$choise)
|
||||
{
|
||||
file_put_contents($this->WayEvents.'/CallbackPayment.json', PHP_EOL.$decrypted_request, FILE_APPEND);
|
||||
|
||||
$fp = fopen($this->WayLog.'/callback.log', 'a');
|
||||
fwrite($fp,' Пришедшие данные для сравнения содержат: '.implode(', ', $ValueInsideJSON)."\n");
|
||||
|
||||
return $ValueInsideJSON;
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
|
||||
public function processSendCallback($response)
|
||||
{
|
||||
$responseAnswer = json_encode(['payments' => $response]);
|
||||
|
||||
$fp = fopen($this->WayLog.'/callback.log', 'a');
|
||||
fwrite($fp,'Ответ отправлен успешно: '.$responseAnswer."\n");
|
||||
|
||||
http_response_code(200);
|
||||
header('Content-Type: application/json');
|
||||
echo $responseAnswer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
session_start();
|
||||
$_SESSION['log_way'] = 'logs';
|
||||
$_SESSION['events_way'] = 'events';
|
||||
?>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
class SetWay
|
||||
{
|
||||
public function __construct() {
|
||||
session_start();
|
||||
}
|
||||
public function SetLogsAndEvensWay($valueLog = '',$valueEvents = '') {
|
||||
$_SESSION['log_way'] = $valueLog;
|
||||
$_SESSION['events_way'] = $valueEvents;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
class CreatingAndTransmittingParametersForConfirm {
|
||||
// private int $marketPlace;
|
||||
private $secretKey;
|
||||
private $items_receipt;
|
||||
private $message;
|
||||
private $request_url;
|
||||
// private $confirmAmount;
|
||||
|
||||
private $jsonString;
|
||||
|
||||
public function __construct($jsonString)
|
||||
{
|
||||
$this->jsonString = $jsonString;
|
||||
|
||||
$this->secretKey = $this->jsonString['secretKey'] ?? null;
|
||||
// $this->confirmAmount = $this->jsonString['confirmAmount'] ?? null;
|
||||
$this->items_receipt = [];
|
||||
$this->message = [];
|
||||
$this->request_url = $this->jsonString['domain'] ?? null;
|
||||
}
|
||||
|
||||
public function addItemToReceipt(string $text, int $quantity, float $price, float $amount)
|
||||
{
|
||||
$this->items_receipt[] = [
|
||||
"text" => $text,
|
||||
"quantity" => $quantity,
|
||||
"price" => $price,
|
||||
"amount" => $amount,
|
||||
"tax" => "vat110",
|
||||
"type" => "full_prepayment",
|
||||
"object" => "commodity",
|
||||
"unit" => "шт."
|
||||
];
|
||||
}
|
||||
|
||||
public function processPayment($jsonString)
|
||||
{
|
||||
|
||||
$sum = 0;
|
||||
|
||||
foreach ($this->items_receipt as $item)
|
||||
{
|
||||
$sum += $item['amount'];
|
||||
}
|
||||
|
||||
$receipt_info = [];
|
||||
|
||||
$this->message = [
|
||||
"marketPlace"=> $this->jsonString['marketPlace'],
|
||||
"orderId"=> $this->jsonString['orderId'],
|
||||
"confirmAmount"=> $sum,
|
||||
];
|
||||
|
||||
$receipt_info["fdReceipt"] = ["taxSystem" => "", "items" => $this->items_receipt];
|
||||
$receipt_info["data"] = $receipt_info;
|
||||
|
||||
// $array1 = $jsonString;
|
||||
|
||||
$this->message = array_merge($this->message + $receipt_info["data"]);
|
||||
// $resultArray = array_merge($array1, $this->message);
|
||||
|
||||
// print_r($resultArray);
|
||||
|
||||
$messageTxt = json_encode($this->message);
|
||||
|
||||
// print_r($messageTxt);
|
||||
|
||||
$signature = hash('sha256', $messageTxt.$this->secretKey);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "https://" .$this->request_url. "/merchantApi/confirmPayment",
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $messageTxt,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Signature: $signature",
|
||||
"Content-Type: application/json"
|
||||
]
|
||||
]);
|
||||
|
||||
$res = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
// spl_autoload_register(function ($class) {
|
||||
include 'Confirm/index.php'; // Предполагается, что каждый класс находится в отдельном файле
|
||||
// });
|
||||
|
||||
class ClassConfirm
|
||||
{
|
||||
public $config;
|
||||
private $array;
|
||||
|
||||
public $WayLog;
|
||||
public $WayEvents;
|
||||
public $Domain;
|
||||
|
||||
public function __construct($array = '')
|
||||
{
|
||||
session_start();
|
||||
$this->WayLog = trim($_SESSION['log_way']);
|
||||
$this->WayEvents = trim($_SESSION['events_way']);
|
||||
|
||||
if (!is_array($array)) {
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'Массив данных не был передан в конструктор', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->array = $array;
|
||||
|
||||
if(empty($this->array['request_url']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'Нет адреса для запроса', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
if((strpos($this->array['request_url'], 'https://oos-stage.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oos.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oosdemo.pscb.ru/')===false))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.' Не Cоответствующий URL', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
$parsed_url = parse_url($this->array['request_url']?? null);
|
||||
|
||||
$this->config = [
|
||||
'domain' => $parsed_url['host'],
|
||||
'orderId'=> $this->array["orderId"],
|
||||
'marketPlace'=> $this->array['marketPlace'],
|
||||
'secretKey'=> $this->array['secretKey'],
|
||||
|
||||
// 'confirmAmount' => $this->array['confirmAmount'],
|
||||
];
|
||||
}
|
||||
|
||||
function CreatePayment($product = '')
|
||||
{
|
||||
|
||||
if (!is_array($product)) {
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'Массив данных чека не был передан', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$paymentParams = new CreatingAndTransmittingParametersForConfirm($this->config);
|
||||
|
||||
foreach ($product as $key1 => $productt)
|
||||
{
|
||||
foreach ($productt as $key2 => $value)
|
||||
{
|
||||
if($key2 == 0 || $key2 == 1)
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'В price либо amount передано значение с《,》необходимо указать не целочисленное значение через《.》', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($product);
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Позиций в чеке: '.$count, FILE_APPEND);
|
||||
|
||||
foreach($product as $prod)
|
||||
{
|
||||
if((!empty($prod["object"]))&&(!empty($prod["quantity"]))&&(!empty($prod["price"]))&&(!empty($prod["amount"])))
|
||||
{
|
||||
$paymentParams->addItemToReceipt($prod["object"],$prod["quantity"], $prod["price"], $prod["amount"]);
|
||||
}
|
||||
else if((empty($prod["object"]))||(empty($prod["quantity"]))||(empty($prod["price"]))||(empty($prod["amount"])))
|
||||
{
|
||||
file_put_contents('logs'.'/confirmation.log',PHP_EOL.'Не указаны или указаны не все составляющие для чека', FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$res = $paymentParams->processPayment($this->config);
|
||||
|
||||
file_put_contents($this->WayEvents.'/ConfirmPayment.json', PHP_EOL.$res);
|
||||
|
||||
$res =json_decode($res);
|
||||
|
||||
foreach($res as $Part_res =>$Value_Part_res)
|
||||
{
|
||||
if($Part_res == 'errorDescription'&&!empty($Value_Part_res))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
if($Part_res == 'errorDescription')
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Есть ошибка в переданных параметрах или повторный OrderID '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
if(empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/confirmation.log',PHP_EOL.'Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
|
||||
// var_dump($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
|
||||
class PaymentParams
|
||||
{
|
||||
private $order_id;
|
||||
private $merchant_id;
|
||||
private $merchant_key;
|
||||
private $request_url;
|
||||
private $success_url;
|
||||
private $fail_url;
|
||||
private $showOrderId;
|
||||
private $hold;
|
||||
private $nonce;
|
||||
private $items_receipt;
|
||||
private $send_receipt;
|
||||
private $message;
|
||||
private $messageText;
|
||||
private $params;
|
||||
private $config;
|
||||
|
||||
public function __construct($config)
|
||||
{
|
||||
$this->config = $config ?? null;
|
||||
|
||||
$this->order_id = $this->config['orderId'] ?? null;
|
||||
|
||||
$this->merchant_id = $this->config['merchant_id'] ?? null;
|
||||
$this->merchant_key = $this->config['merchant_key'] ?? null;
|
||||
$this->request_url = $this->config['domain'] ?? null;
|
||||
$this->success_url = $this->config['success_url'] ?? null;
|
||||
$this->fail_url = $this->config['fail_url'] ?? null;
|
||||
$this->nonce = sha1(time() . "order-123");
|
||||
$this->items_receipt = [];
|
||||
$this->send_receipt = true; // Добавляем инициализацию свойства
|
||||
$this->message = '';
|
||||
$this->params = [];
|
||||
|
||||
$optionalFields =
|
||||
[
|
||||
"showOrderId","details","paymentMethod","customerAccount","customerComment",
|
||||
"customerEmail","customerPhone","displayLanguage","recurrentable","debug",
|
||||
"fdReceipt","hold","merchantData","templates","ac","merchantData",
|
||||
"sbpSubscriptionPurpose","sbpRedirectUrl"
|
||||
];
|
||||
|
||||
foreach($optionalFields as $field)
|
||||
{
|
||||
$this->{$field} = $this->config[$field] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
public function addItemToReceipt(string $text, int $quantity, float $price, float $amount)
|
||||
{
|
||||
$this->items_receipt[] = [
|
||||
"text" => $text,
|
||||
"quantity" => $quantity,
|
||||
"price" => $price,
|
||||
"amount" => $amount,
|
||||
"tax" => "vat110",
|
||||
"type" => "full_prepayment",
|
||||
"object" => "commodity",
|
||||
"unit" => "шт."
|
||||
];
|
||||
}
|
||||
|
||||
public function generateReceipt()
|
||||
{
|
||||
$sum = 0;
|
||||
foreach ($this->items_receipt as $item)
|
||||
{
|
||||
$sum += $item['amount'] ?? null;
|
||||
}
|
||||
|
||||
// Формирование чека по 54-ФЗ
|
||||
if($this->send_receipt)
|
||||
{
|
||||
|
||||
$optionalFields =
|
||||
[
|
||||
"showOrderId","details","paymentMethod","customerAccount","customerComment",
|
||||
"customerEmail","customerPhone","fail_url","success_url","displayLanguage",
|
||||
"recurrentable","debug","fdReceipt"
|
||||
];
|
||||
|
||||
$this->message = [
|
||||
"nonce" => $this->nonce,
|
||||
"amount" => $sum ?? null,
|
||||
"orderId" => $this->order_id ?? null,
|
||||
// "showOrderId" => $this->showOrderId,
|
||||
];
|
||||
|
||||
foreach ($optionalFields as $field) {
|
||||
if ($this->{$field} !== null) {
|
||||
$this->message = array_merge($this->message, [$field => $this->{$field}]);
|
||||
}
|
||||
}
|
||||
|
||||
$dataFields = ["debug","fdReceipt","hold","merchantData","templates","ac","merchantData","sbpSubscriptionPurpose","sbpRedirectUrl"];
|
||||
|
||||
foreach ($dataFields as $field)
|
||||
{
|
||||
if ($this->{$field} !== null)
|
||||
{
|
||||
|
||||
$this->message = array_merge($this->message,
|
||||
[
|
||||
"data" =>
|
||||
[
|
||||
$field => $this->{$field},
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$receipt_info = [];
|
||||
$receipt_info['fdReceipt'] = ["taxSystem" => "", "items" => $this->items_receipt];
|
||||
$this->message['data'] += $receipt_info;
|
||||
}
|
||||
$this->messageText = json_encode($this->message);
|
||||
|
||||
$this->params = [
|
||||
"url" => "https://" .$this->request_url. "/pay",
|
||||
"marketPlace" => $this->merchant_id,
|
||||
"message" => base64_encode($this->messageText),
|
||||
"signature" => hash('sha256', $this->messageText . $this->merchant_key)
|
||||
];
|
||||
}
|
||||
|
||||
public function renderPaymentForm(array $params): string
|
||||
{
|
||||
if (isset($params))
|
||||
{
|
||||
?>
|
||||
<style>
|
||||
#paymentForm
|
||||
{
|
||||
display: none; /* Скрыть форму */
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.getElementById('paymentForm').submit();
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
$html = '<form id="paymentForm" method="post" action="'. $params['url'] .'">';
|
||||
$html .= '<input type="hidden" name="marketPlace" value="'. $params['marketPlace'] .'">';
|
||||
$html .= '<input type="hidden" name="message" value="'. $params['message'] .'">';
|
||||
$html .= '<input type="hidden" name="signature" value="'. $params['signature'] .'">';
|
||||
$html .= '<input type="submit" value="Оплатить">';
|
||||
$html .= '</form>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function getParams(): array
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
// spl_autoload_register(function ($class) {
|
||||
include 'Pay/index.php';
|
||||
|
||||
class ClassPay
|
||||
{
|
||||
public $config;
|
||||
private $array;
|
||||
|
||||
// public $Way = 'logs/';
|
||||
public $WayLog;
|
||||
public $WayEvents;
|
||||
public $Domain;
|
||||
|
||||
public function __construct($array = '')
|
||||
{
|
||||
session_start();
|
||||
$this->WayLog = trim($_SESSION['log_way']);
|
||||
$this->WayEvents = trim($_SESSION['events_way']);
|
||||
|
||||
if (!is_array($array)) {
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'Массив данных не был передан в конструктор', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->array = $array;
|
||||
|
||||
if(empty($this->array['request_url']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'Нет адреса для запроса', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if((strpos($this->array['request_url'], 'https://oos-stage.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oos.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oosdemo.pscb.ru/')===false))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.' Не Cоответствующий URL', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$parsed_url= parse_url($this->array['request_url']?? null);
|
||||
|
||||
$this->config = [
|
||||
'domain' => $parsed_url['host'],
|
||||
'orderId'=> $this->array["orderId"]?? null,
|
||||
'merchant_id'=> $this->array['marketPlace']?? null,
|
||||
'merchant_key'=> $this->array['secretKey']?? null,
|
||||
'request_url'=> $this->array['request_url']?? null,
|
||||
'success_url'=>$this->array['success_url']?? null,
|
||||
'fail_url'=>$this->array['fail_url']?? null,
|
||||
'amount'=>0,
|
||||
'showOrderId' =>$this->array['showOrderId']?? null,
|
||||
'details' => $this->array['details']?? null,
|
||||
'paymentMethod'=>$this->array['paymentMethod']?? null,
|
||||
'customerAccount'=>$this->array['customerAccount']?? null,
|
||||
'customerComment'=>$this->array['customerComment']?? null,
|
||||
'customerEmail'=> $this->array['customerEmail']?? null,
|
||||
'customerPhone'=>$this->array['customerPhone']?? null,
|
||||
'displayLanguage'=>$this->array['displayLanguage']?? null,
|
||||
'recurrentable'=>$this->array['recurrentable']?? null,
|
||||
'debug'=>$this->array['debug']?? null,
|
||||
'hold' =>$this->array['hold']?? false,
|
||||
];
|
||||
|
||||
// echo $Domain;
|
||||
}
|
||||
|
||||
function CreatePayment($product = '')
|
||||
{
|
||||
if (!is_array($product))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'Массив данных для чека не был передан', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
$paymentParams = new PaymentParams($this->config);
|
||||
|
||||
foreach ($product as $key1 => $productt)
|
||||
{
|
||||
foreach ($productt as $key2 => $value)
|
||||
{
|
||||
if($key2 == 0 || $key2 == 1)
|
||||
{
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'В price либо amount передано значение с《,》необходимо указать не целочисленное значение через《.》', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print_r($product);
|
||||
|
||||
$count = count($product);
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Позиций в чеке: '.$count, FILE_APPEND);
|
||||
|
||||
foreach($product as $prod)
|
||||
{
|
||||
if((!empty($prod["object"]))&&(!empty($prod["quantity"]))&&(!empty($prod["price"]))&&(!empty($prod["amount"])))
|
||||
{
|
||||
$paymentParams->addItemToReceipt($prod["object"],$prod["quantity"], $prod["price"], $prod["amount"]);
|
||||
}
|
||||
else if((empty($prod["object"]))||(empty($prod["quantity"]))||(empty($prod["price"]))||(empty($prod["amount"])))
|
||||
{
|
||||
file_put_contents('logs'.'/payment.log',PHP_EOL.'Не указаны или указаны не все составляющие для чека', FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
$paymentParams->generateReceipt();
|
||||
$html = $paymentParams->renderPaymentForm($paymentParams->getParams());
|
||||
|
||||
file_put_contents($this->WayEvents.'/CreatePayResult.json', PHP_EOL.$html, FILE_APPEND);
|
||||
|
||||
|
||||
if ('logs'=== $this->WayLog)
|
||||
{
|
||||
$N = 1;
|
||||
$N.= strlen($this->WayLog);
|
||||
}
|
||||
else
|
||||
if ('logs'!== $this->WayLog)
|
||||
{
|
||||
$N = 0;
|
||||
$N.= strlen($this->WayLog);
|
||||
$N.= strlen('logs');
|
||||
}
|
||||
|
||||
if(!empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Получена команда на запуск модуля ', FILE_APPEND);
|
||||
}
|
||||
if(empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/payment.log',PHP_EOL.'Получена команда на запуск модуля ', FILE_APPEND);
|
||||
}
|
||||
|
||||
echo $html;
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
class CreatingAndTransmittingParametersForInvoicing
|
||||
{
|
||||
private int $marketPlace;
|
||||
private string $secretKey;
|
||||
private $message;
|
||||
private $items_receipt;
|
||||
private $jsonString;
|
||||
private $request_url;
|
||||
private $sbpRedirectUrl;
|
||||
|
||||
public function __construct($jsonString)
|
||||
{
|
||||
$this->jsonString = $jsonString;
|
||||
$this->marketPlace = $this->jsonString['marketPlace'] ?? null;
|
||||
$this->secretKey = $this->jsonString['secretKey'] ?? null;
|
||||
$this->request_url = $this->jsonString['domain'] ?? null;
|
||||
$this->sbpRedirectUrl = $this->jsonString['sbpRedirectUrl'] ?? null;
|
||||
|
||||
$this->items_receipt = [];
|
||||
|
||||
$optionalFields =
|
||||
[
|
||||
"marketPlace","amount","orderId","paymentMethod","showOrderId",
|
||||
"details","customerAccount","customerComment","customerEmail",
|
||||
"customerPhone","expirationFromNow","expirationDateTime",
|
||||
"recurrentable","nonce",
|
||||
|
||||
"user","userPhone","debug","sbpSubscriptionPurpose",
|
||||
|
||||
];
|
||||
foreach($optionalFields as $field)
|
||||
{
|
||||
$this->{$field} = $this->jsonString[$field] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
public function addItemToReceipt(string $text, int $quantity, float $price, float $amount)
|
||||
{
|
||||
$this->items_receipt[] = [
|
||||
"text" => $text,
|
||||
"quantity" => $quantity,
|
||||
"price" => $price,
|
||||
"amount" => $amount,
|
||||
"tax" => "vat110",
|
||||
"type" => "full_prepayment",
|
||||
"object" => "commodity",
|
||||
"unit" => "шт."
|
||||
];
|
||||
}
|
||||
|
||||
public function processPayment2()
|
||||
{
|
||||
|
||||
$sum = 0;
|
||||
foreach ($this->items_receipt as $item)
|
||||
{
|
||||
$sum += $item['amount'];
|
||||
}
|
||||
|
||||
$receipt_info = [];
|
||||
$receipt_info_fd = [];
|
||||
|
||||
if ($this->marketPlace != null)
|
||||
{
|
||||
$this->message = [
|
||||
"marketPlace"=> $this->jsonString['marketPlace'],
|
||||
"orderId"=> $this->jsonString['orderId'],
|
||||
"amount"=> (int)$sum,
|
||||
"requestQrCodeImageUrl"=> false,
|
||||
];
|
||||
}
|
||||
|
||||
$optionalFields =
|
||||
[
|
||||
"marketPlace","amount","orderId","paymentMethod","showOrderId",
|
||||
"details","customerAccount","customerComment","customerEmail",
|
||||
"customerPhone","expirationFromNow","expirationDateTime",
|
||||
"recurrentable","nonce"
|
||||
];
|
||||
|
||||
foreach ($optionalFields as $field) {
|
||||
if ($this->{$field} !== null) {
|
||||
$this->message = array_merge($this->message, [$field => $this->{$field}]);
|
||||
}
|
||||
}
|
||||
$this->message = array_merge($this->message, ["requestQrCodeImageUrl"=> false]);
|
||||
|
||||
$receipt_info_fd["fdReceipt"] = ["taxSystem" => "", "items" => $this->items_receipt];
|
||||
$receipt_info["data"] = ["requestQrCodeImageUrl"=> false,"requestQrCodeImage"=> false,"fdReceipt"=>$receipt_info_fd["fdReceipt"],"sbpRedirectUrl"=>filter_var($this->sbpRedirectUrl, FILTER_VALIDATE_URL) ? $this->sbpRedirectUrl : null];
|
||||
|
||||
$this->message = array_merge($this->message + $receipt_info);
|
||||
|
||||
$newJsonString = json_encode($this->message);
|
||||
|
||||
$values = json_decode($newJsonString, true);
|
||||
|
||||
$messageTxt = json_encode($values);
|
||||
$signature = hash('sha256', $messageTxt.$this->secretKey);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "https://".$this->request_url."/merchantApi/pay",
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $messageTxt,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Signature: $signature",
|
||||
"Content-Type: application/json"
|
||||
]
|
||||
]);
|
||||
|
||||
$res = curl_exec($ch);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
include 'Invoicing/index.php';
|
||||
|
||||
class ClassInvoicing
|
||||
{
|
||||
public $config;
|
||||
private $array;
|
||||
|
||||
public $WayLog;
|
||||
public $WayEvents;
|
||||
|
||||
public function __construct($array = '')
|
||||
{
|
||||
session_start();
|
||||
$this->WayLog = trim($_SESSION['log_way']);
|
||||
$this->WayEvents = trim($_SESSION['events_way']);
|
||||
|
||||
if (!is_array($array)) {
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'Массив данных не был передан в конструктор', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->array = $array;
|
||||
|
||||
if(empty($this->array['request_url']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'Нет адреса для запроса', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
if((strpos($this->array['request_url'], 'https://oos-stage.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oos.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oosdemo.pscb.ru/')===false))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.' Не Cоответствующий URL', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$parsed_url= parse_url($this->array['request_url']?? null);
|
||||
$this->config = [
|
||||
'domain' => $parsed_url['host'],
|
||||
'orderId'=> $this->array["orderId"],
|
||||
'marketPlace'=> $this->array['marketPlace'],
|
||||
'secretKey'=> $this->array['secretKey'],
|
||||
'amount'=> $this->array['amount']?? null,
|
||||
'paymentMethod'=> "sbp",
|
||||
'details'=> $this->array['details']?? null,
|
||||
'customerEmail'=> $this->array['customerEmail']?? null,
|
||||
'sbpRedirectUrl'=> $this->array['sbpRedirectUrl']?? null,
|
||||
'requestQrCodeImage'=> false,
|
||||
'requestQrCodeImageUrl'=> false,
|
||||
];
|
||||
}
|
||||
|
||||
function CreatePayment($product = '')
|
||||
{
|
||||
if (!is_array($product)) {
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'Массив данных для чека не был передан', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$paymentParams = new CreatingAndTransmittingParametersForInvoicing($this->config);
|
||||
|
||||
foreach ($product as $key1 => $productt)
|
||||
{
|
||||
foreach ($productt as $key2 => $value)
|
||||
{
|
||||
if($key2 == 0 || $key2 == 1)
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'В price либо amount передано значение с《,》необходимо указать не целочисленное значение через《.》', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($product);
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Позиций в чеке: '.$count, FILE_APPEND);
|
||||
|
||||
|
||||
foreach($product as $prod)
|
||||
{
|
||||
if((!empty($prod["object"]))&&(!empty($prod["quantity"]))&&(!empty($prod["price"]))&&(!empty($prod["amount"])))
|
||||
{
|
||||
$paymentParams->addItemToReceipt($prod["object"],$prod["quantity"], $prod["price"], $prod["amount"]);
|
||||
}
|
||||
else if((empty($prod["object"]))||(empty($prod["quantity"]))||(empty($prod["price"]))||(empty($prod["amount"])))
|
||||
{
|
||||
file_put_contents('logs'.'/Invoicing.log',PHP_EOL.'Не указаны или указаны не все составляющие для чека', FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$res = $paymentParams->processPayment2();
|
||||
|
||||
file_put_contents($this->WayEvents.'/CreateInvoicing.json', PHP_EOL.$res);
|
||||
|
||||
$res = json_decode($res);
|
||||
|
||||
$url = $res->payment->qrCodePayload;
|
||||
if(!empty($url))
|
||||
{
|
||||
header("Location: $url");
|
||||
echo($url);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
foreach($res as $Part_res =>$Value_Part_res)
|
||||
{
|
||||
if($Part_res == 'errorDescription'&&!empty($Value_Part_res))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'orderId: '.$this->config['orderId'].' '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
if($Part_res == 'errorDescription')
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Есть ошибка в переданных параметрах или повторный OrderID '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
|
||||
if(!empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log', PHP_EOL.$this->config['orderId'].' Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
if(empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/Invoicing.log', PHP_EOL.'Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
class CreatingAndTransmittingParametersForRefund {
|
||||
private int $marketPlace;
|
||||
private string $secretKey;
|
||||
private $items_receipt;
|
||||
private $items_receipt2;
|
||||
private $items_receipt3;
|
||||
private $message;
|
||||
private $jsonString;
|
||||
private $request_url;
|
||||
|
||||
public function __construct($jsonString)
|
||||
{
|
||||
$this->jsonString = $jsonString;
|
||||
$this->marketPlace = $this->jsonString['marketPlace'] ?? null;;
|
||||
$this->secretKey = $this->jsonString['secretKey'] ?? null;
|
||||
$this->request_url = $this->jsonString['domain'] ?? null;
|
||||
$this->items_receipt = [];
|
||||
$this->items_receipt2 = [];
|
||||
$this->message = [];
|
||||
|
||||
}
|
||||
|
||||
public function addItemToReceipt(string $text, int $quantity, float $price, float $amount)
|
||||
{
|
||||
$this->items_receipt[] = [
|
||||
"text" => $text,
|
||||
"quantity" => $quantity,
|
||||
"price" => $price,
|
||||
"amount" => $amount,
|
||||
"tax" => "vat110",
|
||||
"type" => "full_prepayment",
|
||||
"object" => "commodity",
|
||||
"unit" => "шт."
|
||||
];
|
||||
}
|
||||
|
||||
public function processPayment() {
|
||||
|
||||
$sum = 0;
|
||||
|
||||
foreach ($this->items_receipt as $item)
|
||||
{
|
||||
$sum += $item['amount'];
|
||||
}
|
||||
|
||||
$receipt_info = [];
|
||||
|
||||
$this->message = [
|
||||
|
||||
"marketPlace"=> $this->jsonString['marketPlace'],
|
||||
"orderId"=> $this->jsonString['orderId'],
|
||||
"partialRefund"=> $this->jsonString['partialRefund'],
|
||||
"refundSum"=>$sum
|
||||
];
|
||||
|
||||
$receipt_info["fdReceipt"] = ["taxSystem" => "", "items" => $this->items_receipt];
|
||||
$receipt_info["data"] = $receipt_info;
|
||||
|
||||
// $array1 = $jsonString;
|
||||
|
||||
// $this->message = array_merge($this->message + $receipt_info);
|
||||
// $resultArray = array_merge($array1, $this->message);
|
||||
|
||||
// print_r($resultArray);
|
||||
|
||||
$messageTxt = json_encode($this->message);
|
||||
$signature = hash('sha256', $messageTxt.$this->secretKey);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "https://" .$this->request_url. "/merchantApi/refundPayment",
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $messageTxt,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Signature: $signature",
|
||||
"Content-Type: application/json"
|
||||
]
|
||||
]);
|
||||
|
||||
$res = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $res;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
include 'Refund/index.php';
|
||||
|
||||
class ClassRefund
|
||||
{
|
||||
public $config;
|
||||
private $array;
|
||||
|
||||
public $WayLog;
|
||||
public $WayEvents;
|
||||
public $Domain;
|
||||
|
||||
public function __construct($array = '')
|
||||
{
|
||||
session_start();
|
||||
$this->WayLog = trim($_SESSION['log_way']);
|
||||
$this->WayEvents = trim($_SESSION['events_way']);
|
||||
|
||||
if (!is_array($array)) {
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'Массив данных не был передан в конструктор', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->array = $array;
|
||||
|
||||
if(empty($this->array['request_url']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'Нет адреса для запроса', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
if((strpos($this->array['request_url'], 'https://oos-stage.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oos.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oosdemo.pscb.ru/')===false))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.' Не Cоответствующий URL', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$parsed_url= parse_url($this->array['request_url']?? null);
|
||||
$this->config = [
|
||||
'domain' => $parsed_url['host'],
|
||||
'orderId'=> $this->array["orderId"],
|
||||
'marketPlace'=> $this->array['marketPlace'],
|
||||
'secretKey'=> $this->array['secretKey'],
|
||||
'partialRefund'=>$this->array['partialRefund'] ?? false
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
function CreatePayment($product = '')
|
||||
{
|
||||
if (!is_array($product)) {
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'Массив данных для чека не был передан', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$paymentParams = new CreatingAndTransmittingParametersForRefund($this->config);
|
||||
|
||||
foreach ($product as $key1 => $productt)
|
||||
{
|
||||
foreach ($productt as $key2 => $value)
|
||||
{
|
||||
if($key2 == 0 || $key2 == 1)
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'В price либо amount передано значение с《,》необходимо указать не целочисленное значение через《.》', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($product);
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Позиций в чеке: '.$count, FILE_APPEND);
|
||||
|
||||
|
||||
foreach($product as $prod)
|
||||
{
|
||||
if((!empty($prod["object"]))&&(!empty($prod["quantity"]))&&(!empty($prod["price"]))&&(!empty($prod["amount"])))
|
||||
{
|
||||
$paymentParams->addItemToReceipt($prod["object"],$prod["quantity"], $prod["price"], $prod["amount"]);
|
||||
}
|
||||
else if((empty($prod["object"]))||(empty($prod["quantity"]))||(empty($prod["price"]))||(empty($prod["amount"])))
|
||||
{
|
||||
file_put_contents('logs'.'/refund.log',PHP_EOL.'Не указаны или указаны не все составляющие для чека', FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
$res = $paymentParams->processPayment();
|
||||
|
||||
file_put_contents($this->WayEvents.'/RefundPayment.json', PHP_EOL.$res);
|
||||
|
||||
$res =json_decode($res);
|
||||
|
||||
foreach($res as $Part_res =>$Value_Part_res)
|
||||
{
|
||||
if($Part_res == 'errorDescription'&&!empty($Value_Part_res))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'orderId: '.$this->config['orderId'].' '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
if($Part_res == 'errorDescription')
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Есть ошибка в переданных параметрах или повторный OrderID '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
|
||||
if(!empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
if(empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/refund.log',PHP_EOL.'Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
class СancelTransmitting
|
||||
{
|
||||
private int $marketPlace;
|
||||
private string $secretKey;
|
||||
private $jsonString;
|
||||
private $request_url;
|
||||
|
||||
public function __construct($jsonString)
|
||||
{
|
||||
$this->jsonString = $jsonString;
|
||||
|
||||
$this->secretKey = $this->jsonString['secretKey'] ?? null;;
|
||||
$this->request_url = $this->jsonString['domain'] ?? null;
|
||||
}
|
||||
|
||||
public function rejectPayment()
|
||||
{
|
||||
$messageTxt = json_encode($this->jsonString);
|
||||
$signature = hash('sha256', $messageTxt . $this->secretKey);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "https://" .$this->request_url. "/merchantApi/rejectPayment",
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $messageTxt,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
"Signature: $signature",
|
||||
"Content-Type: application/json"
|
||||
]
|
||||
]);
|
||||
|
||||
$res = curl_exec($ch);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
include 'Reject/index.php';
|
||||
|
||||
class ClassReject
|
||||
{
|
||||
public $config;
|
||||
private $array;
|
||||
|
||||
public $WayLog;
|
||||
public $WayEvents;
|
||||
public $Domain;
|
||||
|
||||
public function __construct($array = '')
|
||||
{
|
||||
session_start();
|
||||
$this->WayLog = trim($_SESSION['log_way']);
|
||||
$this->WayEvents = trim($_SESSION['events_way']);
|
||||
|
||||
if (!is_array($array)) {
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.'Массив данных не был передан в конструктор', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->array = $array;
|
||||
|
||||
if(empty($this->array['request_url']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.'Нет адреса для запроса', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
if((strpos($this->array['request_url'], 'https://oos-stage.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oos.pscb.ru/')===false)&&(strpos($this->array['request_url'], 'https://oosdemo.pscb.ru/')===false))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.' Не Cоответствующий URL', FILE_APPEND);
|
||||
exit;
|
||||
}
|
||||
|
||||
$parsed_url= parse_url($this->array['request_url']?? null);
|
||||
|
||||
$this->config = [
|
||||
'domain' => $parsed_url['host'],
|
||||
'orderId'=> $this->array["orderId"],
|
||||
'marketPlace'=> $this->array['marketPlace'],
|
||||
'secretKey'=> $this->array['secretKey']
|
||||
];
|
||||
}
|
||||
|
||||
function CancelPayment()
|
||||
{
|
||||
$paymentParams = new СancelTransmitting($this->config);
|
||||
|
||||
$res = $paymentParams->rejectPayment();
|
||||
|
||||
file_put_contents($this->WayEvents.'/RejectPayment.json', PHP_EOL.$res);
|
||||
|
||||
$res =json_decode($res);
|
||||
|
||||
foreach($res as $Part_res =>$Value_Part_res)
|
||||
{
|
||||
if($Part_res == 'errorDescription'&&!empty($Value_Part_res))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
if($Part_res == 'errorDescription')
|
||||
{
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Есть ошибка в переданных параметрах или повторный OrderID '.$Value_Part_res, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.'orderId: '.$this->config['orderId'].' Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
if(empty($this->config['orderId']))
|
||||
{
|
||||
file_put_contents($this->WayLog.'/cancellation.log',PHP_EOL.'Получена команда на запуск модуля', FILE_APPEND);
|
||||
}
|
||||
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
include 'payment.class.php';
|
||||
|
||||
$data = array(
|
||||
"marketPlace" => 47607,//демо
|
||||
// "marketPlace" => 402938079, //прод
|
||||
"secretKey" => '111111',//демо
|
||||
// "secretKey" => 'ue4z4L00IREoygx52RQH28l62dN6V685',
|
||||
// "secretKey" => '63f779a3b37db5d8e5ddbde00e4ef66d7354cb5572bc3f2f71ebfba14a2d82bc',
|
||||
"orderId" => 3204,
|
||||
// "request_url"=>"https://oos.pscb.ru/cabinet/payments", //прод
|
||||
"request_url"=>"https://oos-stage.pscb.ru/cabinet/payments",//демо
|
||||
"sbpRedirectUrl"=>"ht111234",
|
||||
// "hold" => true,
|
||||
|
||||
);
|
||||
|
||||
$products = array(
|
||||
array(
|
||||
"object" => 'Товар1',
|
||||
"quantity" => 1,
|
||||
"price" => 2,
|
||||
"amount" => 2
|
||||
),
|
||||
array(
|
||||
"object" => 'Товар2',
|
||||
"quantity" => 1,
|
||||
"price" => 2,
|
||||
"amount" => 2
|
||||
),
|
||||
);
|
||||
|
||||
$M = new SetWay();
|
||||
$M->SetLogsAndEvensWay('logs','events');
|
||||
|
||||
$PayForm = new ClassPay($data);
|
||||
$PayForm->CreatePayment($products);
|
||||
|
||||
// $ConfirmPay = new ClassConfirm($data);
|
||||
// $ConfirmPay->CreatePayment($products);
|
||||
|
||||
// $RefundPay = new ClassRefund($data);
|
||||
// $RefundPay->CreatePayment($products);
|
||||
|
||||
// $InvoicingPay = new ClassInvoicing($data);
|
||||
// $InvoicingPay->CreatePayment($products);
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
include 'Src/PayFormClass/PayFormClass.php';
|
||||
include 'Src/PayConfirmClass/ConfirmClass.php';
|
||||
include 'Src/PayInvoicingClass/InvoicingClass.php';
|
||||
include 'Src/PayRefundClass/RefundClass.php';
|
||||
include 'Src/PayRejectClass/RejectClass.php';
|
||||
include 'Src/CallbackClass/CallbackClass.php';
|
||||
include 'Src/LogWay/WayLog.php';
|
||||
?>
|
||||
Loading…
Reference in New Issue