getType() ?? false; $price = $transaction->getPrice() ?? false; $transactionCurrency = $transaction->getCurrency() ?? false; $transactionId = $transaction->getId() ?? false; $transactionComment = $transaction->getComment() ?? false; $vs = $transaction->getVariableSymbol() ?? false; $transactionAccount = $transaction->getAccount(); $orderIdentifiers = $transaction->getOrderIdentifier(); $transactionData = [ 'type' => $type, 'orderIdentifiers' => $orderIdentifiers, 'price' => $price, 'transactionCurrency' => $transactionCurrency, 'transactionAccount' => $transactionAccount, ]; // TMP: Log all payments - #15184 ServiceContainer::getService('logger')->notice('checkPayment', [...$transactionData, 'transactionId' => $transactionId]); if (empty($orderIdentifiers) || !$type || !$transactionCurrency || $price === false || (!empty($this->allowedPaymentTypes) && !in_array($type, $this->allowedPaymentTypes))) { if ($price && ($price > 0)) { addActivityLog(ActivityLog::SEVERITY_WARNING, ActivityLog::TYPE_SYNC, sprintf($this::getName().': '.translate('orderNotFound', 'autoPayment', false, true), $transactionId, $vs), $transactionData, [$this::getLogTag()]); } return; } if (!$orderID = $this->findPaymentOrder($transactionId, $orderIdentifiers, $transactionData)) { return; } $order = new \Order(); $order->createFromDB($orderID); if ($order->getCurrency() != $transactionCurrency) { $currencyContext = Contexts::get(CurrencyContext::class); if (array_key_exists($transactionCurrency, $currencyContext->getSupported())) { $priceConverter = ServiceContainer::getService(PriceConverter::class); $price = $priceConverter->convert($transactionCurrency, $order->getCurrency(), $price)->asFloat(); } else { $data = ['transactionCurrency' => $transactionCurrency]; addActivityLog(ActivityLog::SEVERITY_ERROR, ActivityLog::TYPE_SYNC, sprintf($this::getName().': '.translate('paymentInvalidCurrency', 'autoPayment', false, true), $order->order_no, $transactionCurrency), $data + ActivityLog::addObjectData([$order->id => $order->order_no], 'orders'), [$this::getLogTag()]); return; } } // "číslo protiúčtu" $accountNo = $transaction->getAccountNumber() ?? ''; // "kód banky" $bankCode = $transaction->getBankCode(); $accountNo .= !empty($bankCode) ? "/{$bankCode}" : ''; $paymentId = $this->createPayment($orderID, $price, $transactionId, $accountNo); if ($paymentId) { // v updatePayments() se nastavuje date_handle a následně se neodeslal email sendPaymentReceipt $dateHandleBeforeUpdate = $order->date_handle; $order->updatePayments(); $transactionComment = StringUtil::unicode_trim($transactionComment); $logComment = 'Modul '.$this::getName().' - '.sprintf(translate('orderPaidComment', 'autoPayment', false, true), $transactionId) .((empty($transactionComment)) ? '' : ' '.sprintf(translate('paymentComment', 'autoPayment', false, true), $transactionComment)); if ($order->status_payed == 1 && is_numeric($this->config['newState']) && empty($dateHandleBeforeUpdate)) { $order->changeStatus($this->config['newState'], $logComment, false); } else { $order->logHistory($logComment); } $activityMessage = 'orderPaidActivityFail'; if ($order->status_payed == 1) { $doNotSendEmail = $this->config['doNotSendEmail'] ?? false; if (empty($dateHandleBeforeUpdate) && empty($doNotSendEmail)) { $order->sendPaymentReceipt($paymentId); } $activityMessage = 'orderPaidActivitySuccess'; } $data = ['paymentId' => $paymentId]; addActivityLog(($activityMessage == 'orderPaidActivityFail') ? ActivityLog::SEVERITY_ERROR : ActivityLog::SEVERITY_SUCCESS, ActivityLog::TYPE_SYNC, $this::getName().': '.sprintf(translate($activityMessage, 'autoPayment', false, true), $order->order_no), $data + ActivityLog::addObjectData([$order->id => $order->order_no], 'orders'), [$this::getLogTag()]); } } public function findPaymentOrder($transactionId, $orderIdentifiers, array $transactionData = []) { $qb = $this->getOrderQuery(); $qb->andWhere(Operator::inStringArray($orderIdentifiers, 'order_no')); $orderID = $qb->execute()->fetchColumn(); if (!$orderID) { $qb = $this->getOrderQuery(); $qb->andWhere(Operator::inStringArray($orderIdentifiers, "TRIM(LEADING '0' FROM order_no)")); $orderID = $qb->execute()->fetchColumn(); } if (!$orderID) { $allInOne = join('', $orderIdentifiers); preg_match_all('/(\d{5,})/', $allInOne, $agreements); $qb = $this->getOrderQuery(); $qb->andWhere(Operator::inStringArray($agreements[0], 'order_no')); $orderID = $qb->execute()->fetchColumn(); } if (!$orderID) { $data = $transactionData ?: ['orderIdentifiers' => $orderIdentifiers]; addActivityLog(ActivityLog::SEVERITY_ERROR, ActivityLog::TYPE_SYNC, sprintf($this::getName().': '.translate('orderNotFound', 'autoPayment', false, true), $transactionId, json_encode($orderIdentifiers)), $data, [$this::getLogTag()]); return null; } return $orderID; } public function getOrderQuery() { return sqlQueryBuilder()->select('id') ->from('orders') ->andWhere( Operator::orX( Operator::inIntArray(getStatuses('nothandled'), 'status'), 'TIMESTAMPDIFF(MONTH, date_handle, NOW()) <= 6' ) ) ->orderBy('id', 'DESC') ->sendToMaster(); } protected function createPayment($orderId, $price, $transactionId, string $accountNo = ''): false|int|string { $fields = [ 'id_order' => $orderId, 'price' => $price, 'note' => "Platba č. {$transactionId} modulu ".$this::getName().' '.(!empty($accountNo) ? " č.ú.: {$accountNo}" : ''), 'date' => (new \DateTime())->format('Y-m-d H:i:s'), 'payment_data' => json_encode(['transactionId' => $transactionId]), 'method' => \Payment::METHOD_TRANSFER, ]; $paymentExists = sqlQueryBuilder()->select('id')->from('order_payments') ->where(Operator::equals(['id_order' => $fields['id_order']])) ->andWhere( Operator::orX( Operator::like(['payment_data' => "%\"transactionId\":{$transactionId}%"]), Operator::like(['payment_data' => "%\"transactionId\":\"{$transactionId}\"%"]) )) ->sendToMaster() ->execute()->fetch(); if (!$paymentExists) { return QueryHint::withRouteToMaster(function () use ($fields) { sqlQueryBuilder()->insert('order_payments')->directValues($fields)->execute(); return sqlInsertId(); }); } return false; } public function runCheckPaymentsCron(): bool { if (!$this->isEnabled() || !($this->config['enableCron'] ?? false)) { return true; } return $this->checkPayments(); } public function runCheckPayments(?\DateTime $date = null) { if (!$this->isEnabled()) { return true; } addActivityLog(ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_SYNC, 'Kontrola plateb '.$this->getName().' API (manuálně)', tags: [$this::getLogTag()]); return $this->checkPayments(forceDate: $date); } protected function isEnabled(): bool { return $this->loadConfig() && !($this->config['test'] ?? false); } #[Required] public function setCurlUtil(CurlUtil $curlUtil): void { $this->curlUtil = $curlUtil; } #[Required] public function setSentryLogger(SentryLogger $sentryLogger): void { $this->sentryLogger = $sentryLogger; } }