public function deposit(FinancialTransactionInterface $transaction, $retry)
 {
     $data = $transaction->getExtendedData();
     $authorizationId = $transaction->getPayment()->getApproveTransaction()->getReferenceNumber();
     if (Number::compare($transaction->getPayment()->getApprovedAmount(), $transaction->getRequestedAmount()) === 0) {
         $completeType = 'Complete';
     } else {
         $completeType = 'NotComplete';
     }
     $response = $this->client->requestDoCapture($authorizationId, $transaction->getRequestedAmount(), $completeType, array('CURRENCYCODE' => $transaction->getPayment()->getPaymentInstruction()->getCurrency()));
     $this->throwUnlessSuccessResponse($response, $transaction);
     $details = $this->client->requestGetTransactionDetails($authorizationId);
     $this->throwUnlessSuccessResponse($details, $transaction);
     switch ($details->body->get('PAYMENTSTATUS')) {
         case 'Completed':
             break;
         case 'Pending':
             throw new PaymentPendingException('Payment is still pending: ' . $response->body->get('PENDINGREASON'));
         default:
             $ex = new FinancialException('PaymentStatus is not completed: ' . $response->body->get('PAYMENTSTATUS'));
             $ex->setFinancialTransaction($transaction);
             $transaction->setResponseCode('Failed');
             $transaction->setReasonCode($response->body->get('PAYMENTSTATUS'));
             throw $ex;
     }
     $transaction->setReferenceNumber($authorizationId);
     $transaction->setProcessedAmount($details->body->get('AMT'));
     $transaction->setResponseCode(PluginInterface::RESPONSE_CODE_SUCCESS);
     $transaction->setReasonCode(PluginInterface::REASON_CODE_SUCCESS);
 }
 /**
  * @runInSeparateProcess
  */
 public function testPaymentDetails()
 {
     $client = $this->createClient();
     $this->importDatabaseSchema();
     $em = self::$kernel->getContainer()->get('em');
     $router = self::$kernel->getContainer()->get('router');
     $order = new Order(123.45);
     $em->persist($order);
     $em->flush();
     $crawler = $client->request('GET', $router->generate('payment_details', array('id' => $order->getId())));
     $form = $crawler->selectButton('submit_btn')->form();
     $form['jms_choose_payment_method[method]']->select('paypal_express_checkout');
     $client->submit($form);
     $response = $client->getResponse();
     $this->assertSame(201, $response->getStatusCode(), substr($response, 0, 2000));
     $em->refresh($order);
     $this->assertTrue(Number::compare(123.45, $order->getPaymentInstruction()->getAmount(), '=='));
     $this->assertEquals('bar', $order->getPaymentInstruction()->getExtendedData()->get('foo'));
 }
 /**
  * {@inheritdoc}
  */
 public function deposit(FinancialTransactionInterface $transaction, $retry)
 {
     $data = $transaction->getExtendedData();
     if ($transaction->getResponseCode() !== PluginInterface::RESPONSE_CODE_SUCCESS || $transaction->getReasonCode() !== PluginInterface::REASON_CODE_SUCCESS) {
         $e = new FinancialException('Peyment is not completed');
         $e->setFinancialTransaction($transaction);
         throw $e;
     }
     // różnica kwoty zatwierdzonej i kwoty wymaganej musi być równa zero
     // && nazwa waluty musi się zgadzać
     if (Number::compare($transaction->getProcessedAmount(), $transaction->getRequestedAmount()) === 0 && $transaction->getPayment()->getPaymentInstruction()->getCurrency() == "BTC") {
         // wszystko ok
         // można zakakceptować zamówienie
         $event = new PaymentEvent($this->getName(), $transaction, $transaction->getPayment()->getPaymentInstruction());
         $this->dispatcher->dispatch('deposit', $event);
     } else {
         // coś się nie zgadza, nie można tego zakaceptować
         $e = new FinancialException('The deposit has not passed validation');
         $e->setFinancialTransaction($transaction);
         $transaction->setResponseCode('Unknown');
         $transaction->setReasonCode($data->get('confirmations'));
         throw $e;
     }
 }
Beispiel #4
0
 /**
  * @dataProvider getGreaterFloats
  */
 public function testCompareGreater($float1, $float2)
 {
     $this->assertSame(1, Number::compare($float1, $float2));
 }
 protected function doReverseDeposit(PaymentInterface $payment, $amount)
 {
     $instruction = $payment->getPaymentInstruction();
     if (PaymentInstructionInterface::STATE_VALID !== $instruction->getState()) {
         throw new InvalidPaymentInstructionException('PaymentInstruction must be in STATE_VALID.');
     }
     if (PaymentInterface::STATE_APPROVED !== $payment->getState()) {
         throw new InvalidPaymentException('Payment must be in STATE_APPROVED.');
     }
     $transaction = $instruction->getPendingTransaction();
     if ($transaction === null) {
         if (1 === Number::compare($amount, $max = $instruction->getDepositedAmount() - $instruction->getReversingDepositedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (PaymentInstruction restriction).', $max));
         }
         if (1 === Number::compare($amount, $payment->getDepositedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (Payment restriction).', $payment->getDepositedAmount()));
         }
         $transaction = $this->buildFinancialTransaction();
         $transaction->setTransactionType(FinancialTransactionInterface::TRANSACTION_TYPE_REVERSE_DEPOSIT);
         $transaction->setState(FinancialTransactionInterface::STATE_PENDING);
         $transaction->setRequestedAmount($amount);
         $payment->setReversingDepositedAmount($amount);
         $instruction->setReversingDepositedAmount($instruction->getReversingDepositedAmount() + $amount);
         $retry = false;
     } else {
         if (FinancialTransactionInterface::TRANSACTION_TYPE_REVERSE_DEPOSIT !== $transaction->getTransactionType()) {
             throw new InvalidPaymentInstructionException('There is another pending transaction on this payment.');
         }
         if ($payment->getId() !== $transaction->getPayment()->getId()) {
             throw new InvalidPaymentException('The pending transaction belongs to another Payment.');
         }
         if (1 === Number::compare($amount, $instruction->getReversingDepositedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount cannot be greater than %.2f (PaymentInstruction restriction).', $instruction->getReversingDepositedAmount()));
         }
         if (0 !== Number::compare($amount, $payment->getReversingDepositedAmount())) {
             throw new \InvalidArgumentException(sprintf('$amount must be equal to %.2f (Payment restriction).', $payment->getReversingDepositedAmount()));
         }
         $retry = true;
     }
     $plugin = $this->getPlugin($instruction->getPaymentSystemName());
     try {
         $plugin->reverseDeposit($transaction, $retry);
         $processedAmount = $transaction->getProcessedAmount();
         $payment->setReversingDepositedAmount(0.0);
         $instruction->setReversingDepositedAmount($instruction->getReversingDepositedAmount() - $amount);
         if (PluginInterface::RESPONSE_CODE_SUCCESS === $transaction->getResponseCode()) {
             $transaction->setState(FinancialTransactionInterface::STATE_SUCCESS);
             $payment->setDepositedAmount($payment->getDepositedAmount() - $processedAmount);
             $instruction->setDepositedAmount($instruction->getDepositedAmount() - $processedAmount);
             return $this->buildFinancialTransactionResult($transaction, Result::STATUS_SUCCESS, PluginInterface::REASON_CODE_SUCCESS);
         } else {
             $transaction->setState(FinancialTransactionInterface::STATE_FAILED);
             return $this->buildFinancialTransactionResult($transaction, Result::STATUS_FAILED, $transaction->getReasonCode());
         }
     } catch (PluginFinancialException $ex) {
         $transaction->setState(FinancialTransactionInterface::STATE_FAILED);
         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;
     }
 }