feat: moneta 2.0, MONETA.Assistant payment module for PHPShop 6.7+
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MonetaPhpShop\host;
|
||||
|
||||
use MonetaPhpShop\callback\OrderGateway;
|
||||
use MonetaPhpShop\Money;
|
||||
use MonetaPhpShop\order\Order;
|
||||
use MonetaPhpShop\protocol\TransactionId;
|
||||
use MonetaPhpShop\Settings;
|
||||
use PHPShopOrderFunction;
|
||||
use PHPShopOrm;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Çàêàçû PHPShop (`phpshop_orders`).
|
||||
*
|
||||
* `PHPShopOrm` ñîáèðàåò SQL êîíêàòåíàöèåé, ïîýòîìó â óñëîâèÿ ïîïàäàåò òîëüêî òî, ÷òî óæå
|
||||
* ïðîâåðåíî: öåëîå ÷èñëî èëè íîìåð çàêàçà ïî øàáëîíó {@see TransactionId::ORDER_UID}
|
||||
* (ëàòèíèöà, öèôðû, äåôèñ — áåç êàâû÷åê).
|
||||
*/
|
||||
final class OrderRepository implements OrderGateway
|
||||
{
|
||||
/** Èìÿ ñïîñîáà îïëàòû â æóðíàëå îïëàò ÿäðà (`phpshop_payment.name`). */
|
||||
private const PAYMENT_LOG_NAME = 'Moneta';
|
||||
|
||||
/** Íàçâàíèå ñòàòóñà 101, åñëè åãî åù¸ íåò, — êàê ó ÿäðà (`PHPShopPaymentResult::set_order_status_101()`). */
|
||||
private const STATUS_PAID_BY_GATEWAY_NAME = 'Îïëà÷åíî ïëàòåæíûìè ñèñòåìàìè';
|
||||
|
||||
public function findById(int $id): ?Order
|
||||
{
|
||||
if ($id <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->findOne(['id' => '=' . $id]);
|
||||
}
|
||||
|
||||
public function findByUid(string $uid): ?Order
|
||||
{
|
||||
if (preg_match('/\A' . TransactionId::ORDER_UID . '\z/', $uid) !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->findOne(['uid' => "='" . $uid . "'"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Êàê øòàòíûå ìîäóëè ÿäðà: ñòðîêà â æóðíàëå îïëàò, `changeStatus()` (ïèñüìî ïîêóïàòåëþ,
|
||||
* ñêëàä, ìåññåíäæåðû — ïî íàñòðîéêàì ñòàòóñà) è ôëàã `paid`. `ofd()` ÿäðà íå âûçûâàåòñÿ:
|
||||
* ÷åê ïðîáèâàåò êàññà MONETA.
|
||||
*/
|
||||
public function markPaid(Order $order, int $paidStatus, Money $amount): void
|
||||
{
|
||||
$database = Database::fromHost();
|
||||
if ($paidStatus === Settings::STATUS_PAID_BY_GATEWAY) {
|
||||
$this->ensurePaidByGatewayStatus($database);
|
||||
}
|
||||
$this->logPayment($database, $order, $amount);
|
||||
|
||||
$orderFunction = new PHPShopOrderFunction($order->getId());
|
||||
$orderFunction->changeStatus($paidStatus, $order->getStatusId());
|
||||
$orderFunction->changePaymentStatus(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* `phpshop_payment`: êëþ÷ — íîìåð çàêàçà áåç äåôèñà ÷èñëîì (`4-36` -> 436), ïî íåìó ÿäðî
|
||||
* ïîêàçûâàåò äàòó îïëàòû (`PHPShopOrderFunction::checkPay()`). Íîìåð íå øòàòíîãî âèäà
|
||||
* (ïåðåîïðåäåë¸í õóêîì `setNum`) â ýòó òàáëèöó íå çàïèñûâàåòñÿ — çàïèñü ïðîïóñêàåòñÿ.
|
||||
*/
|
||||
private function logPayment(Database $database, Order $order, Money $amount): void
|
||||
{
|
||||
if (preg_match('/\A([0-9]+)-([0-9]+)\z/', $order->getUid(), $matches) !== 1) {
|
||||
return;
|
||||
}
|
||||
$database->execute(
|
||||
'INSERT IGNORE INTO `' . self::table('payment') . '` (uid, name, sum, datas) VALUES (?, ?, ?, ?)',
|
||||
[(int) ($matches[1] . $matches[2]), self::PAYMENT_LOG_NAME, $amount->toDecimal(), time()],
|
||||
);
|
||||
}
|
||||
|
||||
private function ensurePaidByGatewayStatus(Database $database): void
|
||||
{
|
||||
$database->execute(
|
||||
'INSERT IGNORE INTO `' . self::table('order_status') . "` (id, name, color, external_code, bot_message)"
|
||||
. " VALUES (?, ?, '#ccff00', '', '')",
|
||||
[Settings::STATUS_PAID_BY_GATEWAY, HostCharset::toDatabase(self::STATUS_PAID_BY_GATEWAY_NAME)],
|
||||
);
|
||||
}
|
||||
|
||||
private static function table(string $key): string
|
||||
{
|
||||
$table = $GLOBALS['SysValue']['base'][$key] ?? 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("Íåò òàáëèöû ÿäðà {$key} â êîíôèãóðàöèè.");
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $where
|
||||
*/
|
||||
private function findOne(array $where): ?Order
|
||||
{
|
||||
$orm = new PHPShopOrm($GLOBALS['SysValue']['base']['orders']);
|
||||
$orm->debug = false;
|
||||
$row = $orm->select(['*'], $where, false, ['limit' => 1]);
|
||||
if (!is_array($row) || empty($row['id'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$details = @unserialize((string) ($row['orders'] ?? ''), ['allowed_classes' => false]);
|
||||
if (!is_array($details)) {
|
||||
$details = [];
|
||||
}
|
||||
foreach (['fio', 'tel'] as $field) {
|
||||
if (isset($row[$field]) && is_string($row[$field])) {
|
||||
$row[$field] = HostCharset::fromDatabase($row[$field]);
|
||||
}
|
||||
}
|
||||
// Íàçâàíèÿ òîâàðîâ â êîðçèíå — â êîäèðîâêå ÁÄ, êàê è îñòàëüíûå ñòðîêè çàêàçà.
|
||||
if (isset($details['Cart']['cart']) && is_array($details['Cart']['cart'])) {
|
||||
foreach ($details['Cart']['cart'] as $key => $product) {
|
||||
if (is_array($product) && isset($product['name']) && is_string($product['name'])) {
|
||||
$details['Cart']['cart'][$key]['name'] = HostCharset::fromDatabase($product['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Order::fromRow($row, $details);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user