feat: moneta 2.0, MONETA.Assistant payment module for PHPShop 6.7+
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\host;
|
||||
|
||||
use MonetaPhpShop\callback\OperationJournal;
|
||||
use MonetaPhpShop\ModuleInfo;
|
||||
use MonetaPhpShop\order\Order;
|
||||
use MonetaPhpShop\protocol\CallbackNotification;
|
||||
use MonetaPhpShop\protocol\ResultCode;
|
||||
use MonetaPhpShop\protocol\TransactionId;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Æóðíàë îïåðàöèé — òàáëèöà `[base] moneta_operations` èç `inc/config.ini` ìîäóëÿ.
|
||||
*
|
||||
* Ñòðîêà íà êàæäîå ïîäïèñàííîå óâåäîìëåíèå; ó ñòðîêè çà÷ò¸ííîé îïëàòû çàïîëíåí
|
||||
* `paid_order_id` ñ UNIQUE-êëþ÷îì — âòîðîé çà÷¸ò òîãî æå çàêàçà íåâîçìîæåí äàæå áåç áëîêèðîâêè.
|
||||
* Ïîäïèñü è êîä ïðîâåðêè öåëîñòíîñòè íå õðàíÿòñÿ.
|
||||
*/
|
||||
final class OperationRepository implements OperationJournal
|
||||
{
|
||||
private const COMMAND_PAY = 'PAY';
|
||||
|
||||
/** @var Database */
|
||||
private $database;
|
||||
|
||||
public function __construct(Database $database)
|
||||
{
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
public function findPaidOperation(int $orderId): ?string
|
||||
{
|
||||
$value = $this->database->fetchValue(
|
||||
'SELECT operation_id FROM `' . self::table() . '` WHERE paid_order_id = ? LIMIT 1',
|
||||
[$orderId],
|
||||
);
|
||||
|
||||
return $value === null ? null : (string) $value;
|
||||
}
|
||||
|
||||
public function recordPaid(CallbackNotification $notification, Order $order, string $event): bool
|
||||
{
|
||||
try {
|
||||
$this->insert($notification, $order, $event, ResultCode::paid(), $order->getId());
|
||||
} catch (RuntimeException $exception) {
|
||||
if ($exception->getCode() === Database::ER_DUP_ENTRY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function note(
|
||||
CallbackNotification $notification,
|
||||
?Order $order,
|
||||
string $event,
|
||||
?ResultCode $resultCode
|
||||
): void {
|
||||
$this->insert($notification, $order, $event, $resultCode, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ïîñëåäíèå çàïèñè æóðíàëà äëÿ àäìèíêè, íîâûå ñâåðõó.
|
||||
*
|
||||
* @param string|null $orderUid òîëüêî çàïèñè ýòîãî çàêàçà ({@see TransactionId::orderUidFromInput()}):
|
||||
* ñ ýòèì `order_uid` èëè — åñëè çàêàç íå ðàñïîçíàí — ñ `MNT_TRANSACTION_ID` âèäà `<íîìåð>_…`
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function latest(int $limit, ?string $orderUid = null): array
|
||||
{
|
||||
$where = '';
|
||||
$params = [];
|
||||
if ($orderUid !== null) {
|
||||
// Â íîìåðå çàêàçà íåò `_` è `%` (TransactionId::ORDER_UID) — ýêðàíèðîâàòü â LIKE
|
||||
// íóæíî òîëüêî ñàì ðàçäåëèòåëü `_`.
|
||||
$where = ' WHERE order_uid = ? OR transaction_id LIKE ?';
|
||||
$params = [$orderUid, $orderUid . '\\' . TransactionId::SEPARATOR . '%'];
|
||||
}
|
||||
$params[] = $limit;
|
||||
|
||||
return $this->database->fetchAll(
|
||||
'SELECT id, created_at, command, transaction_id, operation_id, order_id, order_uid, amount,'
|
||||
. ' test_mode, result_code, event FROM `' . self::table() . '`' . $where . ' ORDER BY id DESC LIMIT ?',
|
||||
$params,
|
||||
);
|
||||
}
|
||||
|
||||
public static function table(): string
|
||||
{
|
||||
$table = $GLOBALS['SysValue']['base'][ModuleInfo::PATH]['moneta_operations'] ?? null;
|
||||
// ßâíûé êëàññ, à íå \w: áåç /u \w ñëåäóåò ëîêàëè, à PHPShop ñòàâèò ñâîþ (setlocale â
|
||||
// class/base.class.php) — â cp1251 \w ïðîïóñòèë áû êèðèëëèöó â èìÿ òàáëèöû, êîòîðîå èä¸ò â SQL.
|
||||
if (!is_string($table) || preg_match('/\A[0-9A-Za-z_]+\z/', $table) !== 1) {
|
||||
throw new RuntimeException('Ìîäóëü íå óñòàíîâëåí: íåò òàáëèöû îïåðàöèé â êîíôèãóðàöèè.');
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
private function insert(
|
||||
CallbackNotification $notification,
|
||||
?Order $order,
|
||||
string $event,
|
||||
?ResultCode $resultCode,
|
||||
?int $paidOrderId
|
||||
): void {
|
||||
$amount = $notification->getAmount();
|
||||
$this->database->execute(
|
||||
'INSERT INTO `' . self::table() . '` (created_at, command, transaction_id, operation_id, order_id,'
|
||||
. ' order_uid, amount, test_mode, result_code, event, paid_order_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[
|
||||
time(),
|
||||
$notification->isCheck() ? $notification->getCommand() : self::COMMAND_PAY,
|
||||
$notification->getTransactionId(),
|
||||
$notification->getOperationId(),
|
||||
($order !== null) ? $order->getId() : 0,
|
||||
($order !== null) ? $order->getUid() : '',
|
||||
($amount !== null) ? $amount->toDecimal() : '',
|
||||
$notification->getRawTestMode(),
|
||||
($resultCode !== null) ? $resultCode->getValue() : null,
|
||||
$event,
|
||||
$paidOrderId,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user