/**
  * barbondev.payment.paypoint_hosted.on_gateway_callback event handler
  *
  * @param GatewayCallbackEvent $event
  * @throws \JMS\Payment\CoreBundle\Plugin\Exception\FinancialException
  */
 public function onGatewayCallbackResponse(GatewayCallbackEvent $event)
 {
     $params = $event->getGatewayResponseParams();
     $paymentStatus = new OrderStatus();
     if (isset($params['code']) && PayPointResponseCodes::AUTHORISED == $params['code']) {
         $paymentStatus->setStatus(OrderStatus::STATUS_SUCCESS)->setCode(OrderStatus::CODE_PAYMENT_CAPTURED)->setMessage('Payment captured');
     } else {
         $paymentStatus->setStatus(OrderStatus::STATUS_FAILURE)->setCode(OrderStatus::CODE_PAYMENT_FAILED_TO_CAPTURE)->setMessage('Payment failed');
     }
     $order = $this->em->getRepository('BarbonPaymentPortalBundle:CustomerOrder')->findOneBy(array('paymentInstruction' => $event->getTransaction()->getPayment()->getPaymentInstruction()));
     if (!$order) {
         $this->logger->error('Could not find order for financial transaction reference number {transactionReferenceNumber}', array('transactionReferenceNumber' => $params['trans_id']));
         throw new FinancialException('Could not find order');
     }
     if (!$order->getPaymentStatusCallbackUrl()) {
         return;
     }
     $paymentStatusResponse = new PaymentStatusResponse();
     $paymentStatusResponse->setTransactionUuId($params['trans_id'])->setOrderUuId($order->getUuid())->setAmount((double) $params['amount'])->setCurrency($order->getCurrency())->setPaymentStatus($paymentStatus)->setProcessor($event->getTransaction()->getPayment()->getPaymentInstruction()->getPaymentSystemName())->setPaymentType(CustomerOrder::PAYMENT_TYPE_CARD_PAYMENT)->setPayload($order->getPaymentStatusCallbackPayload());
     $order->setStatusResponse($paymentStatusResponse)->setTransId($params['trans_id']);
     $this->em->persist($order);
     $this->em->flush();
     $paymentStatusResponse->setPayer($order->getPayer());
     $this->callbackNotifier->notifyCallback($order->getPaymentStatusCallbackUrl(), $paymentStatusResponse);
     $redirectUrl = null;
     if (OrderStatus::STATUS_SUCCESS == $paymentStatus->getStatus()) {
         $redirectUrl = $order->getRedirectOnSuccessUrl();
     } elseif (OrderStatus::STATUS_FAILURE == $paymentStatus->getStatus()) {
         $redirectUrl = $order->getRedirectOnFailureUrl();
     }
     if ($redirectUrl) {
         $this->eventDispatcher->addListener(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use($redirectUrl) {
             /* Now, before you go blabbering "what the hell was Dawson thinking when he did this" - I have an explanation
                for you, you jumpy-to-conclusiony developer punk. The reason is that PayPoint does not like it when the post back
                returns anything other than a 200 response - making a 30* redirect at the end of the process like pulling teeth
                or talking to Paul Swift about Toki Pona. It'd be nice not to have JS run the show here - but I'll leave it for you
                to find a better solution as you seem to know everything anyway. Or, you could ask Simon Paulger for the solution.
                If this is Simon Paulger then get Paul Swift to show you a card trick and forget what you've seen here. */
             $event->setResponse(new Response("<html><head><script>(function () { window.location.replace('{$redirectUrl}') })()</script></head><body><a href=\"{$redirectUrl}\">Proceed to last step&hellp;</a></body></html>"));
         });
     }
 }
 /**
  * Action to repeat the payment
  *
  * @param CustomerOrder $order
  * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
  * @throws \Exception
  *
  * @Framework\Route("/order/{uuid}/repeat")
  * @Framework\Template
  */
 public function requestRepeatAction(CustomerOrder $order)
 {
     $instruction = new PaymentInstruction($order->getAmount(), 'GBP', 'paypoint_hosted');
     $this->paymentPluginController->createPaymentInstruction($instruction);
     $order->setPaymentInstruction($instruction);
     $this->em->persist($instruction);
     $this->em->flush();
     $pendingTransaction = $instruction->getPendingTransaction();
     if (null === $pendingTransaction) {
         $payment = $this->paymentPluginController->createPayment($instruction->getId(), $instruction->getAmount());
     } else {
         $payment = $pendingTransaction->getPayment();
     }
     $orderId = $order->getId();
     $amount = -abs($order->getAmount());
     /** @var Result $result */
     $result = $this->paymentPluginController->approveAndDeposit($payment->getId(), $amount);
     /** @var FinancialTransaction $transaction */
     $transaction = $result->getFinancialTransaction();
     if (null === $transaction) {
         throw new FinancialException('No financial transaction for repeat');
     }
     /** @var CustomerOrder $order */
     $order = $this->em->getRepository('BarbonPaymentPortalBundle:CustomerOrder')->find($orderId);
     if (!$order) {
         throw new FinancialException('Could not find order');
     }
     /** @var CustomerOrder $parentOrder */
     $parentOrder = $this->em->getRepository('BarbonPaymentPortalBundle:CustomerOrder')->find($order->getParentId());
     if (!$parentOrder) {
         throw new FinancialException('Could not find parent order');
     }
     if ($order->getPaymentStatusCallbackUrl()) {
         $repeatStatus = new OrderStatus();
         if (Result::STATUS_SUCCESS == $result->getStatus() && !$result->isAttentionRequired()) {
             $repeatStatus->setStatus(OrderStatus::STATUS_SUCCESS)->setCode(OrderStatus::CODE_REPEAT_PAYMENT_CAPTURED)->setMessage('Repeat generated');
         } else {
             $message = 'Repeat failed';
             /** @var ExtendedData $extendedData */
             $extendedData = $transaction->getExtendedData();
             if ($extendedData) {
                 if ($extendedData->has('message')) {
                     $message = $extendedData->get('message');
                 }
             }
             $repeatStatus->setStatus(OrderStatus::STATUS_FAILURE)->setCode(OrderStatus::CODE_REPEAT_PAYMENT_FAILED_TO_CAPTURE)->setMessage($message);
         }
         $repeatStatusResponse = new RepeatStatusResponse();
         $repeatStatusResponse->setOriginalTransactionUuId($parentOrder->getTransId())->setRepeatTransactionUuId($transaction->getReferenceNumber())->setOrderUuId($order->getUuid())->setAmount($transaction->getProcessedAmount())->setCurrency($order->getCurrency())->setRepeatStatus($repeatStatus)->setProcessor($result->getPaymentInstruction()->getPaymentSystemName())->setPaymentType(CustomerOrder::PAYMENT_TYPE_CARD_PAYMENT)->setPayload($order->getPaymentStatusCallbackPayload())->setPayer($order->getPayer());
         $order->setStatusResponse($repeatStatusResponse)->setTransId($transaction->getReferenceNumber());
         $this->em->persist($order);
         $this->em->flush();
         $repeatStatusResponse->setPayer($order->getPayer());
         $this->callbackNotifier->notifyCallback($order->getPaymentStatusCallbackUrl(), $repeatStatusResponse);
         $redirectUrl = null;
         if (Result::STATUS_SUCCESS == $result->getStatus()) {
             $redirectUrl = $order->getRedirectOnSuccessUrl();
         } else {
             if (Result::STATUS_FAILED == $result->getStatus()) {
                 $redirectUrl = $order->getRedirectOnFailureUrl();
             }
         }
         if ($redirectUrl) {
             return new Response("<html><head><script>(function () { window.location.replace('{$redirectUrl}') })()</script></head><body><a href=\"{$redirectUrl}\">Proceed to last step&hellp;</a></body></html>");
         }
     }
     return new Response();
 }