/** * 2016-02-15 * @override * How is a payment method's authorize() used? https://mage2.pro/t/707 * * @see \Magento\Payment\Model\MethodInterface::authorize() * https://github.com/magento/magento2/blob/6ce74b2/app/code/Magento/Payment/Model/MethodInterface.php#L249-L257 * @see \Magento\Payment\Model\Method\AbstractMethod::authorize() * https://github.com/magento/magento2/blob/6ce74b2/app/code/Magento/Payment/Model/Method/AbstractMethod.php#L603-L619 * @param II $payment * @param float $amount * @return $this */ public final function authorize(II $payment, $amount) { /** * 2016-09-05 * Отныне валюта платёжных транзакций настраивается администратором опцией * «Mage2.PRO» → «Payment» → <...> → «Payment Currency» * @see \Df\Payment\Settings::currency() * * 2016-08-19 * Со вчерашнего для мои платёжные модули выполняют платёжные транзакции * не в учётной валюте системы, а в валюте заказа (т.е., витринной валюте). * * Однако это привело к тому, что операция авторизации * стала помечать заказы (платежи) как «Suspected Fraud» (STATUS_FRAUD). * Это происходит из-за кода метода * @see \Magento\Sales\Model\Order\Payment\Operations\AuthorizeOperation::authorize() $isSameCurrency = $payment->isSameCurrency(); if (!$isSameCurrency || !$payment->isCaptureFinal($amount)) { $payment->setIsFraudDetected(true); } * * Метод @see \Magento\Sales\Model\Order\Payment::isSameCurrency() работает так: return !$this->getCurrencyCode() || $this->getCurrencyCode() == $this->getOrder()->getBaseCurrencyCode() ; * По умолчанию $this->getCurrencyCode() возвращает null, * и поэтому isSameCurrency() возвращает true. * Magento, получается, думает, что платёж выполняется в учёной валюте системы, * но вызов $payment->isCaptureFinal($amount) вернёт false, * потому что $amount — размер платежа в учётной валюте системы, а метод устроен так: * @see \Magento\Sales\Model\Order\Payment::isCaptureFinal() $total = $this->getOrder()->getTotalDue(); return $this->amountFormat($total, true) == $this->amountFormat($amountToCapture, true) ; * Т.е. метод сравнивает размер подлежащей оплате стоимости заказа в валюте заказа * с размером текущего платежа, который в учётной валюте системы, * и поэтому вот метод возвращает false. * * Самым разумным решением этой проблемы мне показалось * ручное убирание флага IsFraudDetected */ if ($payment instanceof OP) { $payment->setIsFraudDetected(false); } $this->charge($this->cFromBase($amount), $capture = false); return $this; }