app/Plugin/VeriTrans4G2/Controller/PaymentController.php line 114

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (c) 2018 VeriTrans Inc., a Digital Garage company. All rights reserved.
  4.  * http://www.veritrans.co.jp/
  5.  */
  6. namespace Plugin\VeriTrans4G2\Controller;
  7. use Doctrine\DBAL\Exception\DriverException;
  8. use Doctrine\DBAL\Exception\LockWaitTimeoutException;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Eccube\Common\EccubeConfig;
  11. use Plugin\VeriTrans4G2\Controller\AbstractVt4gController;
  12. use Eccube\Service\CartService;
  13. use Eccube\Service\OrderHelper;
  14. use Eccube\Repository\OrderRepository;
  15. use Eccube\Repository\Master\OrderStatusRepository;
  16. use Plugin\VeriTrans4G2\Entity\Vt4gOrderPayment;
  17. use Plugin\VeriTrans4G2\Entity\Vt4gPaymentMethod;
  18. use Psr\Container\ContainerInterface;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\Routing\Annotation\Route;
  23. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  24. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  25. /**
  26.  * 決済関連コントローラー
  27.  */
  28. class PaymentController extends AbstractVt4gController
  29. {
  30.     /**
  31.      * エンティティーマネージャー
  32.      */
  33.     protected $em;
  34.     /**
  35.      * VT用固定値配列
  36.      */
  37.     protected $vt4gConst;
  38.     /**
  39.      * 汎用処理用ユーティリティ
  40.      */
  41.     protected $util;
  42.     /**
  43.      * @var OrderRepository
  44.      */
  45.     protected $orderRepository;
  46.     /**
  47.      * @var OrderStatusRepository
  48.      */
  49.     protected $orderStatusRepository;
  50.     /**
  51.      * @var CartService
  52.      */
  53.     protected $cartService;
  54.     /**
  55.      * コンストラクタ
  56.      * @param ContainerInterface $container
  57.      * @return void
  58.      */
  59.     public function __construct(
  60.         ContainerInterface $container,
  61.         OrderRepository $orderRepository,
  62.         OrderStatusRepository $orderStatusRepository,
  63.         CartService $cartService,
  64.         EccubeConfig $eccubeConfig,
  65.         EntityManagerInterface $em
  66.     ) {
  67.         $this->container $container;
  68.         $mdkService $this->container->get('vt4g_plugin.service.vt4g_mdk');
  69.         $mdkService->checkMdk();
  70.         $this->em $em;
  71.         $this->vt4gConst $eccubeConfig->get('vt4g_plugin.const');
  72.         $this->util $this->container->get('vt4g_plugin.service.util');
  73.         $this->orderRepository $orderRepository;
  74.         $this->orderStatusRepository $orderStatusRepository;
  75.         $this->cartService $cartService;
  76.     }
  77.     /**
  78.      * 購入フロー決済画面
  79.      *
  80.      * @Route("/shopping/vt4g_payment", name="vt4g_shopping_payment")
  81.      * @param  Request $request リクエストデータ
  82.      * @return object           ビューレスポンス|レダイレクトレスポンス
  83.      */
  84.     public function index(Request $requestCartService $cartServiceOrderRepository $orderRepository)
  85.     {
  86.         $mode $request->get('mode');
  87.         $memo01 null;
  88.         if (!empty($request->get('OrderId'))) {
  89.             $memo01 $request->get('OrderId');
  90.         } elseif (!empty($request->get('orderId'))) {
  91.             $memo01 $request->get('orderId');
  92.         }
  93.         if (!empty($memo01)) {
  94.             $orderPayment $this->em->getRepository(Vt4gOrderPayment::class)->findOneBy(['memo01' => $memo01]);
  95.             //取引IDが登録されていない場合、エラー画面へ遷移
  96.             if (!$orderPayment instanceof Vt4gOrderPayment) {
  97.                 return $this->container->get('vt4g_plugin.service.payment_base')->makeErrorResponse();
  98.             }
  99.             try {
  100.                 list($order$orderPayment) = $this->container->get('vt4g_plugin.service.payment_base')->getLockedOrder($orderPayment->getOrderId());
  101.             } catch (LockWaitTimeoutException $e) {
  102.                 return $this->container->get('vt4g_plugin.service.payment_base')->makeErrorResponse(trans('vt4g_plugin.payment.shopping.lock_timeout'));
  103.             } catch (DriverException $e) {
  104.                 return $this->container->get('vt4g_plugin.service.payment_base')->makeErrorResponse(trans('vt4g_plugin.payment.shopping.lock_timeout'));
  105.             }
  106.             $memo10 unserialize($orderPayment->getMemo10());
  107.             if (!array_key_exists('orderCompleteFlg'$memo10) || $memo10['orderCompleteFlg']) {
  108.                 return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $order->getId()]);
  109.             }
  110.         } elseif (!empty($cartService->getPreOrderId())) {
  111.             $order $orderRepository->findOneBy(['pre_order_id' => $cartService->getPreOrderId()]);
  112.             $orderPayment $this->em->getRepository(Vt4gOrderPayment::class)->createOrderPaymentIfNotExists($order->getId());
  113.             if (is_null($orderPayment)) {
  114.                 return $this->container->get('vt4g_plugin.service.payment_base')->makeErrorResponse();
  115.             }
  116.         } else {
  117.             $order null;
  118.             $orderPayment null;
  119.         }
  120.         // 決済の入力チェック
  121.         $result $this->container->get('vt4g_plugin.service.payment_base')->checkPaymentData($order);
  122.         if ($result !== true) {
  123.             return $result;
  124.         }
  125.         $payment $order->getPayment();
  126.         $payId $this->util->getPayId($payment->getId());
  127.         $payCode $this->util->getPayCode($payId);
  128.         $payload = [
  129.             'paymentType' => $payCode,
  130.             'mode' => $mode,
  131.             'order' => $order,
  132.             'paymentInfo' => $this->util->getPaymentMethodInfo($payment->getId()),
  133.             'user' => $this->getUser(),
  134.             'orderPayment' => $orderPayment,
  135.         ];
  136.         $method "exec{$payCode}Process";
  137.         return $this->$method($request$payload);
  138.     }
  139.     /**
  140.      * 購入フロー決済完了画面
  141.      *
  142.      * @Route("/shopping/vt4g_payment/complete", name="vt4g_shopping_payment_complete")
  143.      * @param  Request $request リクエストデータ
  144.      * @return object           リダイレクトレスポンス
  145.      */
  146.     public function complete(Request $request)
  147.     {
  148.         $orderId $request->get('no');
  149.         $order $this->getOrderById($orderId);
  150.         // 注文が存在しない もしくは ログインユーザと注文者が一致しない場合
  151.         if (!$order) {
  152.             throw new NotFoundHttpException();
  153.         } elseif ($this->getUser() != $order->getCustomer()) {
  154.             $paymentMethod $this->util->getPaymentMethod($order->getPayment()->getId());
  155.             if (
  156.                 !$paymentMethod instanceof Vt4gPaymentMethod
  157.                 || $this->vt4gConst['VT4G_PAYTYPEID_PAYPAY'] != $paymentMethod->getMemo03()
  158.             ) {
  159.                 throw new NotFoundHttpException();
  160.             }
  161.         }
  162.         $orderPayment $this->util->getOrderPayment($order->getId());
  163.         if (!$orderPayment instanceof Vt4gOrderPayment) {
  164.             return $this->container->get('vt4g_plugin.service.payment_base')->makeErrorResponse();
  165.         }
  166.         //ネットバンク決済を使用している時のみ、注文/決済ステータスを変更する。
  167.         $payId $orderPayment->getMemo03();
  168.         if ($payId == $this->vt4gConst['VT4G_PAYTYPEID_BANK']) {
  169.             $bank $this->container->get('vt4g_plugin.service.payment_bank');
  170.             $bank->changePayStatus($order$orderPayment);
  171.         }
  172.         //購入完了後にSlackに通知を送る        
  173.         $url 'https://hooks.slack.com/services/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';
  174.         $order_no $order->getId();
  175.         $company_name $order->getCompanyName();
  176.         $payment_total $order->getPaymentTotal();
  177.         $payment_method "";
  178.         if ($payId == $this->vt4gConst['VT4G_PAYTYPEID_CREDIT']) {
  179.             $payment_method "(クレジットカード決済)";
  180.         }
  181.         if ($this->isGranted('ROLE_USER')) {
  182.             $message "シコメルWebで商品が購入されました。" $payment_method "\n"
  183.                 "ユーザーID: " $this->getUser()->getId() . "\n"
  184.                 "注文番号: " $order_no "\n"
  185.                 "会社名: " $company_name "\n"
  186.                 "支払い総額: " number_format($payment_total) . "円\n";
  187.         } else {
  188.             $message "シコメルWebで商品が購入されました。" $payment_method "\n"
  189.                 "注文番号: " $order_no "\n"
  190.                 "会社名: " $company_name "\n"
  191.                 "支払い総額: " number_format($payment_total) . "円\n";
  192.         }
  193.         $payload json_encode(['text' => $message]);
  194.         $ch curl_init($url);
  195.         curl_setopt($chCURLOPT_POSTtrue);
  196.         curl_setopt($chCURLOPT_POSTFIELDS$payload);
  197.         curl_setopt($chCURLOPT_HTTPHEADER, ['Content-Type: application/json']);
  198.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  199.         // $response = curl_exec($ch);
  200.         curl_close($ch);
  201.         // 完了画面を表示するため、受注IDをセッションに保持する
  202.         $this->session->set(OrderHelper::SESSION_ORDER_ID$order->getId());
  203.         return $this->redirectToRoute('shopping_complete');
  204.     }
  205.     /**
  206.      * 購入フロー決済 戻る処理
  207.      *
  208.      * @Route("/shopping/vt4g_payment/back", name="vt4g_shopping_payment_back")
  209.      * @param  Request $request リクエストデータ
  210.      * @return object           リダイレクトレスポンス
  211.      */
  212.     public function back(Request $request)
  213.     {
  214.         $orderId $request->get('no');
  215.         $order $this->getOrderById($orderId);
  216.         // 注文が存在しない もしくは ログインユーザと注文者が一致しない場合
  217.         if (!$order || $this->getUser() != $order->getCustomer()) {
  218.             throw new NotFoundHttpException();
  219.         }
  220.         return $this->redirectToRoute('shopping');
  221.     }
  222.     /**
  223.      * クレジットカード決済処理
  224.      *
  225.      * @param  Request $request リクエストデータ
  226.      * @param  array   $payload 決済処理に使用するデータ
  227.      * @return object           リダイレクトレスポンス|ビューレスポンス
  228.      */
  229.     private function execCreditProcess($request$payload)
  230.     {
  231.         $credit $this->container->get('vt4g_plugin.service.payment_credit');
  232.         $result false;
  233.         $execPaymentFlg false;
  234.         $error = [
  235.             'payment' => '',
  236.             'credit' => ''
  237.         ];
  238.         // 入力フォーム送信時
  239.         if ($request->getMethod() === 'POST' && $payload['mode'] !== 'comp') {
  240.             $execPaymentFlg true;
  241.             // POST用リクエストパラメータをsessionで指定した値に変更
  242.             if ($request->getSession()->has('vt4g_shopping_request')) {
  243.                 $session $request->getSession();
  244.                 $vt4gShoppingRequest $session->get('vt4g_shopping_request');
  245.                 $request->getSession()->remove('vt4g_shopping_request');
  246.                 $payload['mode'] = $vt4gShoppingRequest['mode'];
  247.                 $payload['customerIp'] = $request->getClientIp();
  248.                 switch ($payload['mode']) {
  249.                     case 'token':   // MDKトークン利用
  250.                     case 'retrade'// 再取引
  251.                     case 'account'// ベリトランス会員ID決済
  252.                         $this->execIsTokenValid($credit$payload);
  253.                         $result $credit->commitNormalPayment($vt4gShoppingRequest$payload$session$error);
  254.                         break;
  255.                     default:
  256.                         return $credit->makeErrorResponse();
  257.                 }
  258.                 if ($result) {
  259.                     if ($payload['paymentInfo']['mpi_flg']) {
  260.                         $redirectUrl $result;
  261.                         return new RedirectResponse($redirectUrl);
  262.                     } else {
  263.                         return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  264.                     }
  265.                 }
  266.             } else {
  267.                 $error['payment'] = trans('vt4g_plugin.payment.shopping.required.error');
  268.                 $result false;
  269.             }
  270.             ;
  271.         }
  272.         if ($payload['mode'] === 'comp') {
  273.             $execPaymentFlg true;
  274.             $session $request->getSession();
  275.             // 本人認証リダイレクト
  276.             $result $credit->commitMpiPayment($request$payload$session$error);
  277.             if ($result) {
  278.                 return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  279.             }
  280.         }
  281.         // 入力フォーム上にエラー表示の場合はロールバックを行わない
  282.         if ($execPaymentFlg && empty($error['credit'])) {
  283.             // ロールバック
  284.             $credit->rollback($payload['order']);
  285.         }
  286.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  287.             'paymentType' => $payload['paymentType'],
  288.             'error' => $error,
  289.             'orderNo' => $payload['order']->getId(),
  290.             'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_10'],
  291.             'tplIsLoading' => (empty($error['payment']) && empty($error['credit'])),
  292.             'loadingImage' => $this->util->getLoadingImage()
  293.         ]);
  294.     }
  295.     /**
  296.      * ATM決済処理
  297.      *
  298.      * @param  request $request リクエストデータ
  299.      * @param  array   $payload 決済処理に使用するデータ
  300.      * @return object           リダイレクトレスポンス|ビューレスポンス
  301.      */
  302.     private function execATMProcess($request$payload)
  303.     {
  304.         $atm $this->container->get('vt4g_plugin.service.payment_atm');
  305.         $error = [
  306.             'payment' => '',
  307.         ];
  308.         if ('POST' === $request->getMethod() && $payload['mode'] == "next") {
  309.             $this->execIsTokenValid($atm$payload);
  310.             $result $atm->atmCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  311.             if ($result) {
  312.                 return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  313.             }
  314.             // ロールバック
  315.             $atm->rollback($payload['order']);
  316.         }
  317.         $paymentMethod $this->util->getPaymentMethod($payload['order']->getPayment()->getId());
  318.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  319.             'paymentType' => $payload['paymentType'],
  320.             'error' => $error,
  321.             'title' => $paymentMethod->getPaymentMethod(),
  322.             'orderNo' => $payload['order']->getId(),
  323.             'tplIsLoading' => empty($error['payment']),
  324.             'loadingImage' => $this->util->getLoadingImage()
  325.         ]);
  326.     }
  327.     /**
  328.      * ネットバンク決済処理
  329.      *
  330.      * @param  request $request リクエストデータ
  331.      * @param  array   $payload 決済処理に使用するデータ
  332.      * @return object           リダイレクトレスポンス|ビューレスポンス
  333.      */
  334.     public function execBankProcess($request$payload)
  335.     {
  336.         $bank $this->container->get('vt4g_plugin.service.payment_bank');
  337.         $error = [
  338.             'payment' => '',
  339.         ];
  340.         // POST用リクエストパラメータ
  341.         $result $bank->bankCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  342.         if ($result == false) {
  343.             // ロールバック
  344.             $bank->rollback($payload['order']);
  345.         }
  346.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  347.             'paymentType' => $payload['paymentType'],
  348.             'error' => $error,
  349.             'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_30'],
  350.             'orderNo' => $payload['order']->getId(),
  351.             'paymentInfo' => $payload['paymentInfo'],
  352.             'tplIsLoading' => empty($error['payment']),
  353.             'loadingImage' => $this->util->getLoadingImage(),
  354.             'requestParam' => $result,
  355.         ]);
  356.     }
  357.     /**
  358.      * コンビニ決済処理
  359.      *
  360.      * @param  Request $request リクエストデータ
  361.      * @param  array   $payload 決済処理に使用するデータ
  362.      * @return object           リダイレクトレスポンス|ビューレスポンス
  363.      */
  364.     private function execCVSProcess($request$payload)
  365.     {
  366.         $cvs $this->container->get('vt4g_plugin.service.payment_cvs');
  367.         $error = [
  368.             'payment' => '',
  369.         ];
  370.         // 入力フォーム送信時
  371.         if ($request->getMethod() === 'POST' && $payload['mode'] == "next") {
  372.             $this->execIsTokenValid($cvs$payload);
  373.             // POST用リクエストパラメータをsessionで指定した値に変更
  374.             if ($request->getSession()->has('vt4g_shopping_request')) {
  375.                 $vt4gCvsForm $request->getSession()->get('vt4g_shopping_request');
  376.                 $request->getSession()->remove('vt4g_shopping_request');
  377.                 //TODO 4.2系と4.3系の分岐が必要そう
  378.                 $request->request->set('payment_cvs'$vt4gCvsForm['conveni']);
  379.                 $result $cvs->cvsCommit($payload['order'], $payload['orderPayment'], $request->request$payload['paymentInfo'], $error);
  380.             } else {
  381.                 $error['payment'] = trans('vt4g_plugin.payment.shopping.required.error');
  382.                 $result false;
  383.             }
  384.             if ($result !== false) {
  385.                 return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  386.             } else {
  387.                 // ロールバック
  388.                 $cvs->rollback($payload['order']);
  389.             }
  390.         }
  391.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  392.             'paymentType' => $payload['paymentType'],
  393.             'error' => $error,
  394.             'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_20'],
  395.             'orderNo' => $payload['order']->getId(),
  396.             'tplIsLoading' => empty($error['payment']),
  397.             'loadingImage' => $this->util->getLoadingImage()
  398.         ]);
  399.     }
  400.     /**
  401.      * Alipay決済処理
  402.      *
  403.      * @param  Request $request リクエストデータ
  404.      * @param  array   $payload 決済処理に使用するデータ
  405.      * @return object           リダイレクトレスポンス|ビューレスポンス
  406.      */
  407.     private function execAlipayProcess($request$payload)
  408.     {
  409.         $alipay $this->container->get('vt4g_plugin.service.payment_alipay');
  410.         $error = [
  411.             'payment' => '',
  412.         ];
  413.         $requestHtml '';
  414.         if ($request->getMethod() === 'POST') {
  415.             if ($payload['mode'] == 'next') {
  416.                 $this->execIsTokenValid($alipay$payload);
  417.                 // リダイレクト用HTML取得
  418.                 $result $alipay->alipayCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  419.                 if ($result !== false) {
  420.                     $requestHtml $result;
  421.                 } else {
  422.                     // ロールバック
  423.                     $alipay->rollback($payload['order']);
  424.                 }
  425.             } else {
  426.                 // 戻り完了処理
  427.                 $result $alipay->alipayComplete($request$payload['order'], $payload['orderPayment'], $error);
  428.                 if ($payload['mode'] == 'success' && $result !== false) {
  429.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  430.                 }
  431.                 // ロールバック
  432.                 $alipay->rollback($payload['order']);
  433.             }
  434.         }
  435.         if ($requestHtml) {
  436.             return new Response(
  437.                 $requestHtml,
  438.                 Response::HTTP_OK,
  439.                 [
  440.                     'Cache-Control' => 'no-store, no-cache',
  441.                     'Pragma' => 'no-cache',
  442.                     'Expires' => '0',
  443.                     'Content-Type' => 'text/html; charset=UTF-8'
  444.                 ]
  445.             );
  446.         } else {
  447.             return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  448.                 'paymentType' => $payload['paymentType'],
  449.                 'error' => $error,
  450.                 'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_50'],
  451.                 'orderNo' => $payload['order']->getId(),
  452.                 'paymentInfo' => $payload['paymentInfo'],
  453.                 'loadingImage' => $this->util->getLoadingImage(),
  454.                 'tplIsLoading' => empty($error['payment']),
  455.             ]);
  456.         }
  457.     }
  458.     /**
  459.      * 銀聯ネット決済処理
  460.      *
  461.      * @param  Request $request リクエストデータ
  462.      * @param  array   $payload 決済処理に使用するデータ
  463.      * @return object           リダイレクトレスポンス|ビューレスポンス
  464.      */
  465.     private function execUPOPProcess($request$payload)
  466.     {
  467.         $upop $this->container->get('vt4g_plugin.service.payment_upop');
  468.         $error = [
  469.             'payment' => '',
  470.         ];
  471.         $requestHtml '';
  472.         if ($request->getMethod() === 'POST') {
  473.             if ($payload['mode'] == "next") {
  474.                 $this->execIsTokenValid($upop$payload);
  475.                 $result $upop->upopCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  476.                 if ($result !== false) {
  477.                     $requestHtml $result;
  478.                 } else {
  479.                     $upop->rollback($payload['order']);
  480.                 }
  481.             }
  482.             // 銀聯ネットから戻った場合
  483.             if ($payload['mode'] == "complete") {
  484.                 $result $upop->upopComplete($request$payload['order'], $payload['orderPayment'], $error);
  485.                 if ($result) {
  486.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  487.                 } else {
  488.                     $upop->rollback($payload['order']);
  489.                 }
  490.             }
  491.         }
  492.         if ($requestHtml) {
  493.             return new Response(
  494.                 $requestHtml,
  495.                 Response::HTTP_OK,
  496.                 [
  497.                     'Cache-Control' => 'no-store, no-cache',
  498.                     'Pragma' => 'no-cache',
  499.                     'Expires' => '0',
  500.                     'Content-Type' => 'text/html; charset=UTF-8'
  501.                 ]
  502.             );
  503.         } else {
  504.             // POST用リクエストパラメータ
  505.             return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  506.                 'paymentType' => $payload['paymentType'],
  507.                 'error' => $error,
  508.                 'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_40'],
  509.                 'orderNo' => $payload['order']->getId(),
  510.                 'tplIsLoading' => empty($error['payment']),
  511.                 'loadingImage' => $this->util->getLoadingImage(),
  512.             ]);
  513.         }
  514.     }
  515.     /**
  516.      * 楽天ペイ処理
  517.      *
  518.      * @param  Request $request リクエストデータ
  519.      * @param  array   $payload 決済処理に使用するデータ
  520.      * @return object           リダイレクトレスポンス|ビューレスポンス
  521.      */
  522.     private function execRakutenProcess($request$payload)
  523.     {
  524.         $rakuten $this->container->get('vt4g_plugin.service.payment_rakuten');
  525.         $error = [
  526.             'payment' => '',
  527.         ];
  528.         $requestHtml '';
  529.         if ($request->getMethod() === 'POST' && $payload['mode'] == "next") {
  530.             $this->execIsTokenValid($rakuten$payload);
  531.             $result $rakuten->rakutenCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  532.             if ($result !== false) {
  533.                 $requestHtml $result;
  534.             } else {
  535.                 $rakuten->rollback($payload['order']);
  536.             }
  537.         }
  538.         if ($request->getMethod() === 'GET') {
  539.             // 楽天から成功で戻った場合
  540.             if ($payload['mode'] == "success") {
  541.                 $result $rakuten->rakutenComplete($request$payload['order'], $payload['orderPayment'], $error);
  542.                 if ($result) {
  543.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  544.                 } else {
  545.                     $rakuten->rollback($payload['order']);
  546.                 }
  547.                 // 楽天からエラーで戻った場合
  548.             } elseif ($payload['mode'] == "error") {
  549.                 // エラー画面用のメッセージを設定してロールバック
  550.                 $rakuten->getResponse($request$payload['order'], $error);
  551.                 $rakuten->rollback($payload['order']);
  552.             }
  553.         }
  554.         if ($requestHtml) {
  555.             return new Response(
  556.                 $requestHtml,
  557.                 Response::HTTP_OK,
  558.                 [
  559.                     'Cache-Control' => 'no-store, no-cache',
  560.                     'Pragma' => 'no-cache',
  561.                     'Expires' => '0',
  562.                     'Content-Type' => 'text/html; charset=UTF-8'
  563.                 ]
  564.             );
  565.         } else {
  566.             return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  567.                 'paymentType' => $payload['paymentType'],
  568.                 'error' => $error,
  569.                 'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_60'],
  570.                 'orderNo' => $payload['order']->getId(),
  571.                 'tplIsLoading' => empty($error['payment']),
  572.                 'loadingImage' => $this->util->getLoadingImage(),
  573.             ]);
  574.         }
  575.     }
  576.     /**
  577.      * 楽天ペイV2処理
  578.      *
  579.      * @param  Request $request リクエストデータ
  580.      * @param  array   $payload 決済処理に使用するデータ
  581.      * @return object           リダイレクトレスポンス|ビューレスポンス
  582.      */
  583.     private function execRakutenv2Process($request$payload)
  584.     {
  585.         $rakutenV2 $this->container->get('vt4g_plugin.service.payment_rakuten_v2');
  586.         $error = [
  587.             'payment' => '',
  588.         ];
  589.         $redirectUrl '';
  590.         if ($request->getMethod() === 'POST' && $payload['mode'] == "next") {
  591.             $this->execIsTokenValid($rakutenV2$payload);
  592.             $result $rakutenV2->rakutenV2Commit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  593.             if ($result !== false) {
  594.                 $redirectUrl $result;
  595.             } else {
  596.                 $rakutenV2->rollback($payload['order']);
  597.             }
  598.         }
  599.         if ($request->getMethod() === 'GET') {
  600.             // 楽天から成功で戻った場合
  601.             if ($payload['mode'] == "success") {
  602.                 $result $rakutenV2->rakutenV2Complete($request$payload['order'], $payload['orderPayment'], $error);
  603.                 if ($result) {
  604.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  605.                 } else {
  606.                     $rakutenV2->rollback($payload['order']);
  607.                 }
  608.                 // 楽天からエラーで戻った場合
  609.             } elseif ($payload['mode'] == "error") {
  610.                 // エラー画面用のメッセージを設定してロールバック
  611.                 $rakutenV2->getResponse($request$payload['order'], $error);
  612.                 $rakutenV2->rollback($payload['order']);
  613.             }
  614.         }
  615.         if ($redirectUrl) {
  616.             return new RedirectResponse($redirectUrl);
  617.         } else {
  618.             return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  619.                 'paymentType' => $payload['paymentType'],
  620.                 'error' => $error,
  621.                 'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_63'],
  622.                 'orderNo' => $payload['order']->getId(),
  623.                 'tplIsLoading' => empty($error['payment']),
  624.                 'loadingImage' => $this->util->getLoadingImage(),
  625.             ]);
  626.         }
  627.     }
  628.     /**
  629.      * リクルートかんたん支払い処理
  630.      *
  631.      * @param  Request $request リクエストデータ
  632.      * @param  array   $payload 決済処理に使用するデータ
  633.      * @return object           リダイレクトレスポンス|ビューレスポンス
  634.      */
  635.     private function execRecruitProcess($request$payload)
  636.     {
  637.         $recruit $this->container->get('vt4g_plugin.service.payment_recruit');
  638.         $error = [
  639.             'payment' => '',
  640.         ];
  641.         if ($request->getMethod() === 'POST' && $payload['mode'] == "next") {
  642.             $this->execIsTokenValid($recruit$payload);
  643.             $result $recruit->recruitCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  644.             if ($result !== false) {
  645.                 // リクルートの画面にリダイレクト
  646.                 return $this->redirect($result);
  647.             } else {
  648.                 $recruit->rollback($payload['order']);
  649.             }
  650.         }
  651.         if ($request->getMethod() === 'GET') {
  652.             // リクルートから成功で戻った場合
  653.             if ($payload['mode'] == "success") {
  654.                 $result $recruit->recruitComplete($request$payload['order'], $payload['orderPayment'], $error);
  655.                 if ($result) {
  656.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  657.                 } else {
  658.                     $recruit->rollback($payload['order']);
  659.                 }
  660.                 // リクルートからエラーで戻った場合
  661.             } elseif ($payload['mode'] == "error") {
  662.                 // エラー画面用のメッセージを設定してロールバック
  663.                 $recruit->getResponse($request$payload['order'], $error);
  664.                 $recruit->rollback($payload['order']);
  665.             }
  666.         }
  667.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  668.             'paymentType' => $payload['paymentType'],
  669.             'error' => $error,
  670.             'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_61'],
  671.             'orderNo' => $payload['order']->getId(),
  672.             'tplIsLoading' => empty($error['payment']),
  673.             'loadingImage' => $this->util->getLoadingImage(),
  674.         ]);
  675.     }
  676.     /**
  677.      * LINE Pay処理
  678.      *
  679.      * @param  Request $request リクエストデータ
  680.      * @param  array   $payload 決済処理に使用するデータ
  681.      * @return object           リダイレクトレスポンス|ビューレスポンス
  682.      */
  683.     private function execLINEPayProcess($request$payload)
  684.     {
  685.         $line $this->container->get('vt4g_plugin.service.payment_linepay');
  686.         $error = [
  687.             'payment' => '',
  688.         ];
  689.         if ($request->getMethod() === 'POST' && $payload['mode'] == "next") {
  690.             $this->execIsTokenValid($line$payload);
  691.             $result $line->linepayCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  692.             if ($result !== false) {
  693.                 // LINEの画面にリダイレクト
  694.                 return $this->redirect($result);
  695.             } else {
  696.                 $line->rollback($payload['order']);
  697.             }
  698.         }
  699.         if ($request->getMethod() === 'GET') {
  700.             // LINEから成功で戻った場合
  701.             if ($payload['mode'] == "success") {
  702.                 $result $line->linepayComplete($request$payload['order'], $payload['orderPayment'], $error);
  703.                 if ($result) {
  704.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  705.                 } else {
  706.                     $line->rollback($payload['order']);
  707.                 }
  708.                 // LINEからエラーで戻った場合
  709.             } elseif ($payload['mode'] == "error") {
  710.                 // エラー画面用のメッセージを設定してロールバック
  711.                 $line->getResponse($request$payload['order'], $error);
  712.                 $line->rollback($payload['order']);
  713.                 // LINEからキャンセルで戻った場合
  714.             } elseif ($payload['mode'] == "cancel") {
  715.                 // レスポンスをログに出力、ロールバックしてご注文手続き画面へ
  716.                 $line->getResponse($request$payload['order'], $error);
  717.                 $line->rollback($payload['order']);
  718.                 return $this->redirectToRoute('vt4g_shopping_payment_back', ['no' => $payload['order']->getId()]);
  719.             }
  720.         }
  721.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  722.             'paymentType' => $payload['paymentType'],
  723.             'error' => $error,
  724.             'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_62'],
  725.             'orderNo' => $payload['order']->getId(),
  726.             'tplIsLoading' => empty($error['payment']),
  727.             'loadingImage' => $this->util->getLoadingImage(),
  728.         ]);
  729.     }
  730.     /**
  731.      * PayPal決済処理
  732.      *
  733.      * @param  Request $request リクエストデータ
  734.      * @param  array   $payload 決済処理に使用するデータ
  735.      * @return object           リダイレクトレスポンス|ビューレスポンス
  736.      */
  737.     private function execPayPalProcess($request$payload)
  738.     {
  739.         $paypal $this->container->get('vt4g_plugin.service.payment_paypal');
  740.         $error = [
  741.             'payment' => '',
  742.         ];
  743.         if ($request->getMethod() === 'POST' && $payload['mode'] == 'next') {
  744.             $this->execIsTokenValid($paypal$payload);
  745.             $result $paypal->PayPalCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  746.             if ($result !== false) {
  747.                 return $this->redirect($result);
  748.             } else {
  749.                 // ロールバック
  750.                 $paypal->rollback($payload['order']);
  751.             }
  752.         }
  753.         if ($request->getMethod() === 'GET') {
  754.             // paypalから成功で戻った場合
  755.             if ($payload['mode'] == 'exec') {
  756.                 $result $paypal->PayPalComplete($request$payload['order'], $payload['orderPayment'], $error);
  757.                 if ($result !== false) {
  758.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  759.                 } else {
  760.                     // ロールバック
  761.                     $paypal->rollback($payload['order']);
  762.                 }
  763.                 // paypalからキャンセルで戻った場合
  764.             } elseif ($payload['mode'] == 'back') {
  765.                 $paypal->rollback($payload['order']);
  766.                 return $this->redirectToRoute('vt4g_shopping_payment_back', ['no' => $payload['order']->getId()]);
  767.             }
  768.         }
  769.         // POST用リクエストパラメータ
  770.         return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  771.             'paymentType' => $payload['paymentType'],
  772.             'error' => $error,
  773.             'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_70'],
  774.             'orderNo' => $payload['order']->getId(),
  775.             'paymentInfo' => $payload['paymentInfo'],
  776.             'tplIsLoading' => empty($error['payment']),
  777.             'loadingImage' => $this->util->getLoadingImage()
  778.         ]);
  779.     }
  780.     /**
  781.      * PayPay処理
  782.      *
  783.      * @param  Request $request リクエストデータ
  784.      * @param  array   $payload 決済処理に使用するデータ
  785.      * @return object           リダイレクトレスポンス|ビューレスポンス
  786.      */
  787.     private function execPayPayProcess($request$payload)
  788.     {
  789.         $paypay $this->container->get('vt4g_plugin.service.payment_paypay');
  790.         $error = [
  791.             'payment' => '',
  792.         ];
  793.         $redirectUrl '';
  794.         if ($request->getMethod() === 'POST') {
  795.             if ($payload['mode'] == "next") {
  796.                 $this->execIsTokenValid($paypay$payload);
  797.                 $result $paypay->PayPayCommit($payload['order'], $payload['orderPayment'], $payload['paymentInfo'], $error);
  798.                 if ($result !== false) {
  799.                     $redirectUrl $result;
  800.                 } else {
  801.                     $paypay->rollback($payload['order']);
  802.                 }
  803.             }
  804.         }
  805.         if ($request->getMethod() === 'GET') {
  806.             // PayPayから成功で戻った場合
  807.             if ($payload['mode'] == "success") {
  808.                 $result $paypay->PayPayComplete($request$payload['order'], $payload['orderPayment'], $error);
  809.                 if ($result) {
  810.                     return $this->redirectToRoute('vt4g_shopping_payment_complete', ['no' => $payload['order']->getId()]);
  811.                 } else {
  812.                     $paypay->rollback($payload['order']);
  813.                 }
  814.                 // PayPayからエラーで戻った場合
  815.             } elseif ($payload['mode'] == "error") {
  816.                 // エラー画面用のメッセージを設定してロールバック
  817.                 $paypay->getResponse($request$payload['order'], $error);
  818.                 $paypay->rollback($payload['order']);
  819.                 // PayPayからキャンセルで戻った場合
  820.             } elseif ($payload['mode'] == "cancel") {
  821.                 // レスポンスをログに出力、ロールバックしてご注文手続き画面へ
  822.                 $paypay->getResponse($request$payload['order'], $error);
  823.                 $paypay->rollback($payload['order']);
  824.                 return $this->redirectToRoute('vt4g_shopping_payment_back', ['no' => $payload['order']->getId()]);
  825.             }
  826.         }
  827.         if ($redirectUrl) {
  828.             return new RedirectResponse($redirectUrl);
  829.         } else {
  830.             // POST用リクエストパラメータ
  831.             return $this->render('VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment.twig', [
  832.                 'paymentType' => $payload['paymentType'],
  833.                 'error' => $error,
  834.                 'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_80'],
  835.                 'orderNo' => $payload['order']->getId(),
  836.                 'tplIsLoading' => empty($error['payment']),
  837.                 'loadingImage' => $this->util->getLoadingImage(),
  838.             ]);
  839.         }
  840.     }
  841.     /**
  842.      * 注文IDから受注データを取得
  843.      *
  844.      * @param  integer $orderId 注文ID
  845.      * @return \Eccube\Entity\Order            Orderクラスインスタンス
  846.      */
  847.     private function getOrderById($orderId)
  848.     {
  849.         return $this->orderRepository->findOneBy([
  850.             'id' => $orderId
  851.         ]);
  852.     }
  853.     /**
  854.      * isTokenValidを実行し、例外が発生している場合はポイント等のロールバックを行う。
  855.      *
  856.      * @param  object  $paymentService   各支払のサービスクラス
  857.      * @param  array   $payload          決済処理に使用するデータ
  858.      *
  859.      * @throws AccessDeniedHttpException isTokenValidでトークンが有効ではないと判定された場合
  860.      */
  861.     private function execIsTokenValid($paymentService$payload)
  862.     {
  863.         try {
  864.             //CSRFチェック
  865.             $this->isTokenValid();
  866.         } catch (AccessDeniedHttpException $e) {
  867.             //ロールバックとエラー画面への遷移
  868.             $paymentService->rollback($payload['order']);
  869.             throw new AccessDeniedHttpException($e->getMessage());
  870.         }
  871.     }
  872. }