app/Plugin/GmoEpsilon4/Controller/PaymentController.php line 161

Open in your IDE?
  1. <?php
  2. namespace Plugin\GmoEpsilon4\Controller;
  3. use Eccube\Common\EccubeConfig;
  4. use Eccube\Controller\AbstractController;
  5. use Eccube\Entity\Master\OrderStatus;
  6. use Eccube\Entity\Order;
  7. use Eccube\Repository\MailHistoryRepository;
  8. use Eccube\Repository\Master\OrderStatusRepository;
  9. use Eccube\Repository\OrderRepository;
  10. use Eccube\Service\CartService;
  11. use Eccube\Service\MailService;
  12. use Eccube\Service\PurchaseFlow\PurchaseContext;
  13. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  14. use Eccube\Service\ShoppingService;
  15. use Plugin\GmoEpsilon4\Repository\ConfigRepository;
  16. use Plugin\GmoEpsilon4\Service\GmoEpsilonRequestService;
  17. use Plugin\GmoEpsilon4\Util\PaymentUtil;
  18. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  23. use Twig_Environment;
  24. /**
  25.  * リンク式決済の注文/戻る/完了通知を処理する.
  26.  */
  27. class PaymentController extends AbstractController
  28. {
  29.     /**
  30.      * @var OrderRepository
  31.      */
  32.     protected $orderRepository;
  33.     /**
  34.      * @var OrderStatusRepository
  35.      */
  36.     protected $orderStatusRepository;
  37.     /**
  38.      * @var PurchaseFlow
  39.      */
  40.     protected $purchaseFlow;
  41.     /**
  42.      * @var CartService
  43.      */
  44.     protected $cartService;
  45.     /**
  46.      * @var MailHistoryRepository
  47.      */
  48.     protected $mailHistoryRepository;
  49.     /**
  50.      * PaymentController constructor.
  51.      *
  52.      * @param OrderRepository $orderRepository
  53.      * @param ShoppingService $shoppingService
  54.      * @param MailHistoryRepository $mailHistoryRepository
  55.      */
  56.     public function __construct(
  57.         EccubeConfig $eccubeConfig,
  58.         Twig_Environment $twig,
  59.         OrderRepository $orderRepository,
  60.         OrderStatusRepository $orderStatusRepository,
  61.         PurchaseFlow $shoppingPurchaseFlow,
  62.         CartService $cartService,
  63.         MailService $mailService,
  64.         ConfigRepository $configRepository,
  65.         GmoEpsilonRequestService $gmoEpsilonRequestService,
  66.         MailHistoryRepository $mailHistoryRepository
  67.     ) {
  68.         $this->eccubeConfig $eccubeConfig;
  69.         $this->twig $twig;
  70.         $this->orderRepository $orderRepository;
  71.         $this->orderStatusRepository $orderStatusRepository;
  72.         $this->purchaseFlow $shoppingPurchaseFlow;
  73.         $this->cartService $cartService;
  74.         $this->mailService $mailService;
  75.         $this->gmoEpsilonRequestService $gmoEpsilonRequestService;
  76.         $this->mailHistoryRepository $mailHistoryRepository;
  77.         $this->Config $configRepository->get();
  78.         $this->objPayUtil = new PaymentUtil($this->eccubeConfig);
  79.     }
  80.     /**
  81.      * @Route("/shopping/epsilon_payment/back", name="gmo_epsilon4_back")
  82.      *
  83.      * @param Request $request
  84.      *
  85.      * @return RedirectResponse
  86.      */
  87.     public function back(Request $request)
  88.     {
  89.         $orderId $this->objPayUtil->getOrderId($request->get('order_number'));
  90.         $Order $this->getOrderByNo($orderId);
  91.         if (!$Order) {
  92.             throw new NotFoundHttpException();
  93.         }
  94.         if ($this->getUser() != $Order->getCustomer()) {
  95.             throw new NotFoundHttpException();
  96.         }
  97.         // 受注ステータスを購入処理中へ変更
  98.         $OrderStatus $this->orderStatusRepository->find(OrderStatus::PROCESSING);
  99.         $Order->setOrderStatus($OrderStatus);
  100.         // purchaseFlow::rollbackを呼び出し, 購入処理をロールバックする.
  101.         $this->purchaseFlow->rollback($Order, new PurchaseContext());
  102.         $this->entityManager->flush();
  103.         return $this->redirectToRoute('shopping');
  104.     }
  105.     /**
  106.      * 完了画面へ遷移する.
  107.      *
  108.      * @Route("/shopping/epsilon_payment/complete", name="gmo_epsilon4_complete")
  109.      */
  110.     public function complete(Request $request)
  111.     {
  112.         $orderId $this->objPayUtil->getOrderId($request->get('order_number'));
  113.         logs('gmo_epsilon')->addInfo('決済完了通知 : start.'.print_r($request->getContent(),true));
  114.         if (empty($orderId)) {
  115.             // コンビニ(後払い系も?)の場合、sessionからorderNoを拾う
  116.             $orderId $this->session->get('eccube.plugin.epsilon.orderId', []);
  117.         }
  118.         logs('gmo_epsilon')->addInfo('orderId='.$orderId);
  119.         // 決済処理中の受注を取得
  120.         $Order $this->getOrderByNo($orderId);
  121.         if (!$Order || empty($Order)) {
  122.             // レスポンスにorder_numberが含まれていない決済を考慮してオーダー情報確認CGIから受注番号を取得
  123.             $arrXML $this->getOrderInfo($request->get('trans_code'));
  124.             $err_code $this->gmoEpsilonRequestService->getXMLValue($arrXML'RESULT''ERR_CODE');
  125.             if (empty($err_code)) {
  126.                 $orderNo $this->gmoEpsilonRequestService->getXMLValue($arrXML'RESULT''ORDER_NUMBER');
  127.                 $orderId $this->objPayUtil->getOrderId($orderNo);
  128.                 $Order $this->orderRepository->find($orderId);
  129.             }
  130.             if (!$Order || empty($Order)) {
  131.                 logs('gmo_epsilon')->addInfo('NotFoundHttpException : オーダー情報が取得できない');
  132.                 throw new NotFoundHttpException();
  133.             }
  134.         }
  135.         // Check the order was completed
  136.         if ($Order->getGmoEpsilonOrderNo()) {
  137.             log_info('[注文確認] 注文が完了しました.', [$Order->getId()]);
  138.             return $this->redirectToRoute('shopping_error');
  139.         }
  140.         if ($this->getUser() != $Order->getCustomer()) {
  141.             throw new NotFoundHttpException();
  142.         }
  143.         if (!is_null($Order->getPayment())) {
  144.             $method_class $Order->getPayment()->getMethodClass();
  145.             // 決済方法に応じたインスタンスを取得
  146.             $PaymentMethod $this->container->get($method_class);
  147.             $PaymentMethod->setOrder($Order);
  148.             $PaymentMethod->setRequest($request);
  149.             // メールリンク決済の場合、選択された支払方法を取得
  150.             if (preg_match('/Maillink/'$method_class)) {
  151.                 $arrXML $this->getOrderInfo($request->get('trans_code'));
  152.                 // エラーチェック
  153.                 $err_code $this->gmoEpsilonRequestService->getXMLValue($arrXML'RESULT''ERR_CODE');
  154.                 if (empty($err_code)) {
  155.                     $PaymentMethod->payment_code $this->gmoEpsilonRequestService->getXMLValue($arrXML'RESULT''PAYMENT_CODE');
  156.                 }
  157.             }
  158.         }
  159.         // 購入完了処理
  160.         $PaymentMethod->compProcess();
  161.         // FIXME 完了画面を表示するため, 受注IDをセッションに保持する
  162.         $this->session->set('eccube.front.shopping.order.id'$Order->getId());
  163.         $this->entityManager->flush();
  164.         return $this->redirectToRoute('shopping_complete');
  165.     }
  166.     /**
  167.      * 結果通知URLを受け取る.
  168.      *
  169.      * @Route("/epsilon_receive_complete", name="gmo_epsilon4_receive_complete")
  170.      */
  171.     public function receiveComplete(Request $request)
  172.     {
  173.         logs('gmo_epsilon')->addInfo('決済完了通知 : start.');
  174.         // 注文完了画面の処理と競合するため、処理を遅らせる
  175.         sleep(10);
  176.         // 決済会社から受注番号を受け取る
  177.         $orderId $this->objPayUtil->getOrderId($request->get('order_number'));
  178.         logs('gmo_epsilon')->addInfo('orderId='.$orderId);
  179.         $Order $this->getOrderByNo($orderId);
  180.         if (!$Order || empty($Order)) {
  181.             $Order $this->orderRepository->findOneBy(['order_no' => $orderId]);
  182.             if (!$Order || empty($Order)) {
  183.                 logs('gmo_epsilon')->error('決済完了通知 : Not Found Order. POST param argument ' print_r($request->getContent(), true));
  184.                 // 異常応答
  185.                 return new Response(0);
  186.             }
  187.             logs('gmo_epsilon')->addInfo('決済完了通知 : end. 対象データ処理済み');
  188.             // 正常終了 完了画面で処理済み
  189.             return new Response(1);
  190.         }
  191.         $contract_code $this->Config->getContractCode();
  192.         if ($contract_code != $request->get('contract_code') ||
  193.                 empty($request->get('trans_code')) ||
  194.                 empty($request->get('state'))
  195.         ) {
  196.             logs('gmo_epsilon')->error('決済完了通知 : POST param argument ' print_r($request->getContent(), true));
  197.             // 異常応答
  198.             return new Response(0);
  199.         }
  200.         // Get order status before updating
  201.         $orderStatusIdBefore $Order->getOrderStatus()->getId();
  202.         // purchaseFlow::commitを呼び出し, 購入処理を完了させる.
  203.         $this->purchaseFlow->commit($Order, new PurchaseContext());
  204.         // 受注ステータスを新規受付へ変更
  205.         $OrderStatus $this->orderStatusRepository->find(OrderStatus::NEW);
  206.         $Order->setOrderStatus($OrderStatus);
  207.         $Order->setPaymentDate(new \DateTime());
  208.         // 会員の場合、購入回数、購入金額などを更新
  209.         if ($Customer $Order->getCustomer()) {
  210.             $this->orderRepository->updateOrderSummary($Customer);
  211.         }
  212.         // トランザクションコードを登録
  213.         $Order->setTransCode($request->get('trans_code'));
  214.         // カートを削除する
  215.         $this->cartService->clear();
  216.         // メール送信
  217.         $MailHistory $this->mailHistoryRepository->findBy(['Order' => $Order]);
  218.         /**
  219.          * ■操作と現象
  220.          * ユーザーが決済処理をした直後に画面を閉じたりした時
  221.          * ①イプシロン側の決済処理は完了
  222.          * ②ECCUBE側が決済処理中のまま
  223.          * ■決済完了通知の動き
  224.          * イプシロン側の処理は完了 してるので、決済完了通知がくる。
  225.          * 既にECCUBE側の決済処理が完了している場合は対象データ処理済みで終了。
  226.          * 決済処理中ならステータスの更新等の決済処理をする。
  227.          * メール送信の処理は必ず入れるが、メール履歴(dtb_mail_history)を確認して無ければ送信の判断を入れる。
  228.          */
  229.         if (!$MailHistory && $orderStatusIdBefore != OrderStatus::NEW) {
  230.             $MailHistory $this->mailService->sendOrderMail($Order);
  231.         }
  232.         $this->entityManager->flush();
  233.         logs('gmo_epsilon')->addInfo('決済完了通知 : end.');
  234.         // 正常応答
  235.         return new Response(1);
  236.     }
  237.     /**
  238.      * 結果通知URLを受け取る.
  239.      *
  240.      * @Route("/epsilon_receive_conveni_and_payeasy_complete", name="gmo_epsilon4_receive_conveni_and_payeasy_complete")
  241.      */
  242.     public function receiveConveniAndPayeasyComplete(Request $request)
  243.     {
  244.         logs('gmo_epsilon')->addInfo('決済完了通知(コンビニ、ペイジー) : start.');
  245.         // 受注情報を取得
  246.         $Order $this->orderRepository->findOneBy([
  247.             'order_no' => $this->objPayUtil->getOrderId($request->get('order_number')),
  248.             'trans_code' => $request->get('trans_code'),
  249.         ]);
  250.         if (!$Order) {
  251.             logs('gmo_epsilon')->error('決済完了通知 : Not Found Order. POST param argument ' print_r($request->getContent(), true));
  252.             // 異常応答
  253.             return new Response(0);
  254.         }
  255.         // 受注ステータスを対応中へ変更
  256.         $OrderStatus $this->orderStatusRepository->find(OrderStatus::IN_PROGRESS);
  257.         $Order->setOrderStatus($OrderStatus);
  258.         $Order->setPaymentDate(new \DateTime());
  259.         $this->entityManager->flush();
  260.         logs('gmo_epsilon')->addInfo('決済完了通知(コンビニ、ペイジー) : end.');
  261.         // 正常応答
  262.         return new Response(1);
  263.     }
  264.     /**
  265.      * 注文番号で受注を検索する.
  266.      *
  267.      * @param $orderId
  268.      *
  269.      * @return Order
  270.      */
  271.     private function getOrderByNo($orderId)
  272.     {
  273.         /** @var OrderStatus $pendingOrderStatus */
  274.         $pendingOrderStatus $this->orderStatusRepository->find(OrderStatus::PENDING);
  275.         /** @var Order $Order */
  276.         $Order $this->orderRepository->findOneBy([
  277.             'order_no' => $orderId,
  278.             'OrderStatus' => $pendingOrderStatus,
  279.         ]);
  280.         return $Order;
  281.     }
  282.     function getOrderInfo($trans_code)
  283.     {
  284.         $info_conf_url $this->Config->getInfoConfUrl();
  285.         $contract_code $this->Config->getContractCode();
  286.         // リクエストパラメータを設定
  287.         $arrParameter = array(
  288.             'contract_code' => $contract_code,
  289.             'trans_code' => $trans_code,
  290.         );
  291.         // リクエスト送信
  292.         $arrXML $this->gmoEpsilonRequestService->sendData($info_conf_url$arrParameter);
  293.         return $arrXML;
  294.     }
  295. }