コード例 #1
0
 protected function constructFinancialTransactionResult(FinancialTransactionInterface $transaction, $status, $reasonCode)
 {
     $this->financialTransaction = $transaction;
     $this->credit = $transaction->getCredit();
     $this->payment = $transaction->getPayment();
     $this->paymentInstruction = null !== $this->credit ? $this->credit->getPaymentInstruction() : $this->payment->getPaymentInstruction();
     $this->status = $status;
     $this->reasonCode = $reasonCode;
     $this->recoverable = false;
 }
コード例 #2
0
 protected function doReverseCredit(CreditInterface $credit, $amount)
 {
     $instruction = $credit->getPaymentInstruction();
     if (PaymentInstructionInterface::STATE_VALID !== $instruction->getState()) {
         throw new InvalidPaymentInstructionException('PaymentInstruction must be in STATE_VALID.');
     }
     if (CreditInterface::STATE_CREDITED !== $credit->getState()) {
         throw new InvalidCreditException('Credit must be in STATE_CREDITED.');
     }
     if (false === $credit->isIndependent()) {
         $payment = $credit->getPayment();
         if (PaymentInterface::STATE_APPROVED !== $payment->getState() && PaymentInterface::STATE_EXPIRED !== $payment->getState()) {
             throw new InvalidPaymentException('Payment must be in STATE_APPROVED, or STATE_EXPIRED.');
         }
     }
     $transaction = $instruction->getPendingTransaction();
     if (null === $transaction) {
         if (1 === Number::compare($amount, $max = $instruction->getCreditedAmount() - $instruction->getReversingCreditedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (PaymentInstruction restriction).', $max));
         }
         if (1 === Number::compare($amount, $credit->getCreditedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (Credit restriction).', $credit->getCreditedAmount()));
         }
         if (false === $credit->isIndependent() && 1 === Number::compare($amount, $max = $payment->getCreditedAmount() - $payment->getReversingCreditedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (Payment restriction).', $max));
         }
         $transaction = $this->buildFinancialTransaction();
         $transaction->setTransactionType(FinancialTransactionInterface::TRANSACTION_TYPE_REVERSE_CREDIT);
         $transaction->setRequestedAmount($amount);
         $credit->addTransaction($transaction);
         $credit->setReversingCreditedAmount($amount);
         $instruction->setReversingCreditedAmount($instruction->getReversingCreditedAmount() + $amount);
         if (false === $credit->isIndependent()) {
             $payment->setReversingCreditedAmount($payment->getReversingCreditedAmount() + $amount);
         }
         $retry = false;
     } else {
         if (FinancialTransactionInterface::TRANSACTION_TYPE_REVERSE_CREDIT !== $transaction->getTransactionType()) {
             throw new InvalidPaymentInstructionException('Pending transaction is not of TYPE_REVERSE_CREDIT.');
         }
         if ($credit->getId() !== $transaction->getCredit()->getId()) {
             throw new InvalidCreditException('Pending transaction belongs to another Credit.');
         }
         if (1 === Number::compare($amount, $instruction->getReversingCreditedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (PaymentInstruction restriction).', $instruction->getReversingCreditedAmount()));
         }
         if (0 !== Number::compare($amount, $credit->getReversingCreditedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount must be equal to %.2f (Credit restriction).', $credit->getReversingCreditedAmount()));
         }
         if (false === $credit->isIndependent() && 1 === Number::compare($amount, $payment->getReversingCreditedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (Payment restriction).', $payment->getReversingCreditedAmount()));
         }
         $retry = true;
     }
     $plugin = $this->getPlugin($instruction->getPaymentSystemName());
     try {
         $plugin->reverseCredit($transaction, $amount);
         $processedAmount = $transaction->getProcessedAmount();
         if (PluginInterface::RESPONSE_CODE_SUCCESS === $transaction->getResponseCode()) {
             $transaction->setState(FinancialTransactionInterface::STATE_SUCCESS);
             $credit->setReversingCreditedAmount(0.0);
             $instruction->setReversingCreditedAmount($instruction->getReversingCreditedAmount() - $amount);
             $credit->setCreditedAmount($credit->getCreditedAmount() - $processedAmount);
             $instruction->setCreditedAmount($instruction->getCreditedAmount() - $processedAmount);
             if (false === $credit->isIndependent()) {
                 $payment->setReversingCreditedAmount($payment->getReversingCreditedAmount() - $amount);
                 $payment->setCreditedAmount($payment->getCreditedAmount() - $processedAmount);
             }
             return $this->buildFinancialTransactionResult($transaction, Result::STATUS_SUCCESS, PluginInterface::REASON_CODE_SUCCESS);
         } else {
             $transaction->setState(FinancialTransactionInterface::STATE_FAILED);
             $credit->setReversingCreditedAmount(0.0);
             $instruction->setReversingCreditedAmount($instruction->getReversingCreditedAmount() - $amount);
             if (false === $credit->isIndependent()) {
                 $payment->setReversingCreditedAmount($payment->getReversingCreditedAmount() - $amount);
             }
             return $this->buildFinancialTransactionResult($transaction, Result::STATUS_FAILED, $transaction->getReasonCode());
         }
     } catch (PluginFinancialException $ex) {
         $transaction->setState(FinancialTransactionInterface::STATE_FAILED);
         $credit->setReversingCreditedAmount(0.0);
         $instruction->setReversingCreditedAmount($instruction->getReversingCreditedAmount() - $amount);
         if (false === $credit->isIndependent()) {
             $payment->setReversingCreditedAmount($payment->getReversingCreditedAmount() - $amount);
         }
         return $this->buildFinancialTransactionResult($transaction, Result::STATUS_FAILED, $transaction->getReasonCode());
     } catch (PluginBlockedException $blocked) {
         $transaction->setState(FinancialTransactionInterface::STATE_PENDING);
         if ($blocked instanceof PluginTimeoutException) {
             $reasonCode = PluginInterface::REASON_CODE_TIMEOUT;
         } else {
             if ($blocked instanceof PluginActionRequiredException) {
                 $reasonCode = PluginInterface::REASON_CODE_ACTION_REQUIRED;
             } else {
                 if (null === ($reasonCode = $transaction->getReasonCode())) {
                     $reasonCode = PluginInterface::REASON_CODE_BLOCKED;
                 }
             }
         }
         $transaction->setReasonCode($reasonCode);
         $transaction->setResponseCode(PluginInterface::RESPONSE_CODE_PENDING);
         $result = $this->buildFinancialTransactionResult($transaction, Result::STATUS_PENDING, $reasonCode);
         $result->setPluginException($blocked);
         $result->setRecoverable();
         return $result;
     }
 }