app/Plugin/CodeacLinepay/Controller/PaymentController.php line 250

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * https://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Plugin\CodeacLinepay\Controller;
  13. use Eccube\Controller\AbstractController;
  14. use Eccube\Entity\Master\OrderStatus;
  15. use Eccube\Entity\Order;
  16. use Eccube\Repository\Master\OrderStatusRepository;
  17. use Eccube\Repository\OrderRepository;
  18. use Eccube\Service\CartService;
  19. use Eccube\Service\PurchaseFlow\PurchaseContext;
  20. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  21. use Eccube\Service\OrderStateMachine;
  22. use Exception;
  23. use GuzzleHttp\Exception\ConnectException;
  24. use Plugin\CodeacLinepay\Entity\PaymentStatus;
  25. use Plugin\CodeacLinepay\Repository\ConfigRepository;
  26. use Plugin\CodeacLinepay\Repository\PaymentStatusRepository;
  27. use Plugin\CodeacLinepay\Repository\CvsPaymentStatusRepository;
  28. use Plugin\CodeacLinepay\Service\LinePay\LineClient;
  29. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  30. use Symfony\Component\HttpFoundation\RedirectResponse;
  31. use Symfony\Component\HttpFoundation\Request;
  32. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  33. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  34. use Plugin\CodeacLinepay\Util\PayClient;
  35. use Plugin\CodeacLinepay\Repository\PayPayConfigRepository;
  36. /**
  37.  * リンク式決済の注文/戻る/完了通知を処理する.
  38.  */
  39. class PaymentController extends AbstractController
  40. {
  41.     /**
  42.      * @var OrderRepository
  43.      */
  44.     protected $orderRepository;
  45.     /**
  46.      * @var OrderStatusRepository
  47.      */
  48.     protected $orderStatusRepository;
  49.     /**
  50.      * @var PaymentStatusRepository
  51.      */
  52.     protected $paymentStatusRepository;
  53.     /**
  54.      * @var CvsPaymentStatusRepository
  55.      */
  56.     protected $cvsPaymentStatusRepository;
  57.     /**
  58.      * @var PurchaseFlow
  59.      */
  60.     protected $purchaseFlow;
  61.     /**
  62.      * @var CartService
  63.      */
  64.     protected $cartService;
  65.     /**
  66.      * @var OrderStateMachine
  67.      */
  68.     protected $orderStateMachine;
  69.     /**
  70.      * @var ConfigRepository
  71.      */
  72.     public $configRepository;
  73.     /**
  74.      * @var PayPayConfigRepository
  75.      */
  76.     public $payconfigRepository;
  77.     /**
  78.      * PaymentController constructor.
  79.      *
  80.      * @param OrderRepository $orderRepository
  81.      * @param OrderStatusRepository $orderStatusRepository
  82.      * @param PaymentStatusRepository $paymentStatusRepository
  83.      * @param PurchaseFlow $shoppingPurchaseFlow,
  84.      * @param CartService $cartService
  85.      * @param OrderStateMachine $orderStateMachine
  86.      */
  87.     public function __construct(
  88.         OrderRepository $orderRepository,
  89.         OrderStatusRepository $orderStatusRepository,
  90.         PaymentStatusRepository $paymentStatusRepository,
  91.         PurchaseFlow $shoppingPurchaseFlow,
  92.         CartService $cartService,
  93.         OrderStateMachine $orderStateMachine,
  94.         ConfigRepository $configRepository,
  95.         PayPayConfigRepository $payconfigRepository
  96.     ) {
  97.         $this->orderRepository $orderRepository;
  98.         $this->orderStatusRepository $orderStatusRepository;
  99.         $this->paymentStatusRepository $paymentStatusRepository;
  100.         $this->purchaseFlow $shoppingPurchaseFlow;
  101.         $this->cartService $cartService;
  102.         $this->orderStateMachine $orderStateMachine;
  103.         $this->configRepository $configRepository;
  104.         $this->payconfigRepository $payconfigRepository;
  105.     }
  106.     /**
  107.      * @Route("/line_payment_back", name="line_payment_back")
  108.      *
  109.      * @param Request $request
  110.      *
  111.      * @return RedirectResponse
  112.      */
  113.     public function back(Request $request)
  114.     {
  115.         $orderNo $request->get('orderId');
  116.         $Order $this->getOrderByNo($orderNo);
  117.         if (!$Order) {
  118.             throw new NotFoundHttpException();
  119.         }
  120.         if ($this->getUser() != $Order->getCustomer()) {
  121.             throw new NotFoundHttpException();
  122.         }
  123.         // change status to during purchase process
  124.         $OrderStatus $this->orderStatusRepository->find(OrderStatus::PROCESSING);
  125.         $Order->setOrderStatus($OrderStatus);
  126.         // change status to unsettled
  127.         $PaymentStatus $this->paymentStatusRepository->find(PaymentStatus::OUTSTANDING);
  128.         $Order->setCodeacLinepayPaymentStatus($PaymentStatus);
  129.         // purchaseFlow::rollbackを呼び出し, 購入処理をロールバックする.
  130.         $this->purchaseFlow->rollback($Order, new PurchaseContext());
  131.         $this->entityManager->flush();
  132.         return $this->redirectToRoute('shopping');
  133.     }
  134.     /**
  135.      * 完了画面へ遷移する.
  136.      *
  137.      * @Route("/line_payment_complete", name="line_payment_complete")
  138.      * @throws Exception
  139.      */
  140.     public function complete(Request $requestSessionInterface $session)
  141.     {
  142.         $orderNo $request->get('orderId');
  143.         $transactionId $request->get('transactionId');
  144.         $lineOrder $session->get('linePayOrder');
  145.         $Order $this->getOrderByNo($orderNo);
  146.         if (!$Order) {
  147.             throw new NotFoundHttpException();
  148.         }
  149.         if ($this->getUser() != $Order->getCustomer()) {
  150.             throw new NotFoundHttpException();
  151.         }
  152.         if (!$Order) {
  153.             throw new NotFoundHttpException();
  154.         }
  155.         //check for valid transaction id
  156.         if ($lineOrder['transactionId'] != $transactionId) {
  157.             return $this->redirectToRoute('shopping_error');
  158.         }
  159.         //confirm line payment
  160.         try {
  161.             $config $this->configRepository->get(1);
  162.             $linePay = new LineClient([
  163.                 'channelId' => $config->getLineChannelId(),
  164.                 'channelSecret' => $config->getLineChannelSecret(),
  165.                 'isSandbox' => (bool)$config->getSandbox(),
  166.             ]);
  167.             $response $linePay->confirm($lineOrder['transactionId'], [
  168.                 'amount' => (int) $lineOrder['params']['amount'],
  169.                 'currency' => $lineOrder['params']['currency'],
  170.             ]);
  171.             //redirect to error page if confirmation is not successful
  172.             if (!$response->isSuccessful()) {
  173.                 $lineOrder['confirmCode'] = $response['returnCode'];
  174.                 $lineOrder['confirmMessage'] = $response['returnMessage'];
  175.                 $lineOrder['isSuccessful'] = false;
  176.                 $session->set('linePayOrder'$lineOrder);
  177.                 return $this->redirectToRoute('shopping_error');
  178.             } else {
  179.                 //make sale paid
  180.                 $paymentData $response->getInfo();
  181.                 // change order status to new
  182.                 $OrderStatus $this->orderStatusRepository->find(OrderStatus::PAID);
  183.                 $Order->setOrderStatus($OrderStatus);
  184.                 //change payment status to actual sale
  185.                 $PaymentStatus $this->paymentStatusRepository->find(PaymentStatus::ACTUAL_SALES);
  186.                 $Order->setCodeacLinepayPaymentStatus($PaymentStatus);
  187.                 $Order->setCodeacLinepayPaymentData(json_encode($paymentData));
  188.                 // add message to order completion email
  189.                 $Order->appendCompleteMailMessage('');
  190.                 // purchaseFlow::commitを呼び出し, 購入処理を完了させる.
  191.                 $this->purchaseFlow->commit($Order, new PurchaseContext());
  192.                 //$this->entityManager->flush();
  193.             }
  194.         } catch (ConnectException $e) {
  195.             //            die("Confirm API timeout! A recheck mechanism should be implemented.");
  196.             return $this->redirectToRoute('shopping_error');
  197.         }
  198.         // カートを削除する
  199.         $this->cartService->clear();
  200.         // FIXME 完了画面を表示するため, 受注IDをセッションに保持する
  201.         $this->session->set('eccube.front.shopping.order.id'$Order->getId());
  202.         $this->entityManager->flush();
  203.         return $this->redirectToRoute('shopping_complete');
  204.     }
  205.     /**
  206.      * 完了画面へ遷移する.
  207.      *
  208.      * @Route("/paypay_payment_complete", name="paypay_payment_complete")
  209.      * @throws Exception
  210.      */
  211.     public function paypay_complete(Request $requestSessionInterface $session)
  212.     {
  213.         $orderNo $request->get('orderId');
  214.         $transactionId $request->get('transactionId');
  215.         $payOrder $session->get('payPayOrder');
  216.         $Order $this->getOrderByNo($orderNo);
  217.         if (!$Order) {
  218.             $last_payorder $session->get('payPayOrder');
  219.             if(isset($last_payorder['LAST_ORDER'])){
  220.                 if($last_payorder['LAST_ORDER'] == $orderNo){
  221.                     $session->set('payPayOrder', []);
  222.                     return $this->redirectToRoute('mypage');
  223.                 }
  224.             }
  225.             throw new NotFoundHttpException();
  226.         }
  227.         if ($this->getUser() != $Order->getCustomer()) {
  228.             throw new NotFoundHttpException();
  229.         }
  230.         //check for valid transaction id
  231.         if ($payOrder['transactionId'] != $transactionId) {
  232.             return $this->redirectToRoute('shopping_error');
  233.         }
  234.         //confirm line payment
  235.         try {
  236.             $config $this->payconfigRepository->get(1);
  237.             $payPay = new PayClient([
  238.                 'API_KEY' => $config->getApiId(),
  239.                 'API_SECRET' => $config->getApiSecret(),
  240.                 'MERCHANT_ID' => $config->getMemberId()
  241.             ], (bool) $config->getProduction());
  242.             $response =  $payPay->code->getPaymentDetails($payOrder['transactionId']);
  243.             $data $response['data'];
  244.             if ($response['resultInfo']['code'] == 'SUCCESS') {
  245.                 if ($data['status'] === "COMPLETED") {
  246.                     //make sale paid
  247.                     $paymentData $data;
  248.                     $OrderStatus $this->orderStatusRepository->find(OrderStatus::PAID);
  249.                     $Order->setOrderStatus($OrderStatus);
  250.                     $PaymentStatus $this->paymentStatusRepository->find(PaymentStatus::ACTUAL_SALES);
  251.                     $Order->setCodeacPaypayPaymentStatus($PaymentStatus);
  252.                     $Order->setCodeacPaypayPaymentData(json_encode($paymentData));
  253.                     $Order->appendCompleteMailMessage('');
  254.                     $payOrder = [];
  255.                     $payOrder['LAST_ORDER'] = $orderNo;
  256.                     $session->set('payPayOrder'$payOrder);
  257.                     $this->purchaseFlow->commit($Order, new PurchaseContext());
  258.                 } else if ($data['status'] === "CREATED") {
  259.                     //make sale paid
  260.                     $paymentData $data;
  261.                     $OrderStatus $this->orderStatusRepository->find(OrderStatus::PROCESSING);
  262.                     $Order->setOrderStatus($OrderStatus);
  263.                     $PaymentStatus $this->paymentStatusRepository->find(PaymentStatus::OUTSTANDING);
  264.                     $Order->setCodeacPaypayPaymentStatus($PaymentStatus);
  265.                     $Order->setCodeacPaypayPaymentData(json_encode($paymentData));
  266.                     $this->purchaseFlow->rollback($Order, new PurchaseContext());
  267.                     $this->entityManager->flush();
  268.                     return $this->redirectToRoute('shopping');
  269.                 } else {
  270.                     $payOrder['confirmCode'] = $response['resultInfo']['code'];
  271.                     $payOrder['confirmMessage'] = $response['resultInfo']['message'];
  272.                     $payOrder['isSuccessful'] = false;
  273.                     $session->set('payPayOrder'$payOrder);
  274.                     return $this->redirectToRoute('shopping_error');
  275.                 }
  276.             } else {
  277.                 $payOrder['confirmCode'] = $response['resultInfo']['code'];
  278.                 $payOrder['confirmMessage'] = $response['resultInfo']['message'];
  279.                 $payOrder['isSuccessful'] = false;
  280.                 $session->set('payPayOrder'$payOrder);
  281.                 return $this->redirectToRoute('shopping_error');
  282.             }
  283.         } catch (ConnectException $e) {
  284.             return $this->redirectToRoute('shopping_error');
  285.         }
  286.         // カートを削除する
  287.         $this->cartService->clear();
  288.         // FIXME 完了画面を表示するため, 受注IDをセッションに保持する
  289.         $this->session->set('eccube.front.shopping.order.id'$Order->getId());
  290.         $this->entityManager->flush();
  291.         return $this->redirectToRoute('shopping_complete');
  292.     }
  293.     /**
  294.      * 注文番号で受注を検索する.
  295.      *
  296.      * @param $orderNo
  297.      *
  298.      * @return Order
  299.      */
  300.     private function getOrderByNo($orderNo)
  301.     {
  302.         /** @var OrderStatus $pendingOrderStatus */
  303.         $pendingOrderStatus $this->orderStatusRepository->find(OrderStatus::PENDING);
  304.         $outstandingPaymentStatus $this->paymentStatusRepository->find(PaymentStatus::OUTSTANDING);
  305.         /** @var Order $Order */
  306.         $Order $this->orderRepository->findOneBy([
  307.             'order_no' => $orderNo,
  308.             'OrderStatus' => $pendingOrderStatus,
  309.             'CodeacLinepayPaymentStatus' => $outstandingPaymentStatus,
  310.         ]);
  311.         return $Order;
  312.     }
  313.     private function getCompletedOrder($orderNo)
  314.     {
  315.         /** @var OrderStatus $pendingOrderStatus */
  316.         // $pendingOrderStatus = $this->orderStatusRepository->find(OrderStatus::PAID);
  317.         // $outstandingPaymentStatus = $this->paymentStatusRepository->find(PaymentStatus::ACTUAL_SALES);
  318.         /** @var Order $Order */
  319.         $Order $this->orderRepository->findOneBy([
  320.             'order_no' => $orderNo
  321.         ]);
  322.         return $Order;
  323.     }
  324. }