app/Plugin/StripeRec42/Controller/ShoppingExController.php line 81

Open in your IDE?
  1. <?php
  2. namespace Plugin\StripeRec42\Controller;
  3. if( \file_exists(dirname(__FILE__).'/../../StripePaymentGateway42/vendor/stripe/stripe-php/init.php')) {
  4.     include_once(dirname(__FILE__).'/../../StripePaymentGateway42/vendor/stripe/stripe-php/init.php');
  5. }
  6. use Plugin\StripeRec42\Service\CouponService;
  7. use Plugin\StripeRec42\Service\PointBundleService;
  8. use Plugin\StripeRec42\Service\RecurringService;
  9. use Plugin\StripeRec42\Service\UtilService;
  10. use Stripe\Webhook;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\Routing\Annotation\Route;
  13. use Eccube\Controller\ShoppingController;
  14. use Psr\Container\ContainerInterface;
  15. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  16. use Symfony\Component\HttpFoundation\RequestStack;
  17. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  18. use Eccube\Controller\AbstractController;
  19. use Eccube\Service\CartService;
  20. use Eccube\Service\MailService;
  21. use Eccube\Service\OrderHelper;
  22. use Eccube\Entity\BaseInfo;
  23. use Eccube\Entity\Order;
  24. use Eccube\Entity\Customer;
  25. use Eccube\Form\Type\Shopping\OrderType;
  26. use Eccube\Repository\OrderRepository;
  27. use Eccube\Service\PurchaseFlow\PurchaseContext;
  28. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  29. use Eccube\Common\EccubeConfig;
  30. use Eccube\Entity\Master\OrderStatus;
  31. use Eccube\Entity\TradeLaw;
  32. use Plugin\StripePaymentGateway42\Repository\StripeConfigRepository;
  33. use Plugin\StripePaymentGateway42\StripeClient;
  34. use Plugin\StripePaymentGateway42\Entity\StripeConfig;
  35. use Plugin\StripePaymentGateway42\Entity\StripeOrder;
  36. use Plugin\StripePaymentGateway42\Entity\StripeLog;
  37. use Plugin\StripePaymentGateway42\Entity\StripeCustomer;
  38. use Plugin\StripeRec42\Service\ConfigService;
  39. use Plugin\StripeRec42\Entity\StripeRecOrder;
  40. use Plugin\StripeRec42\Repository\StripeRecOrderRepository;
  41. use Plugin\StripeRec42\Service\MailExService;
  42. use Stripe\PaymentMethod;
  43. use Stripe\PaymentIntent;
  44. use Eccube\Repository\BaseInfoRepository;
  45. use Eccube\Repository\TradeLawRepository;
  46. use Symfony\Component\RateLimiter\RateLimiterFactory;
  47. use Doctrine\ORM\EntityManagerInterface;
  48. use Eccube\Common\Constant;
  49. use Symfony\Component\DependencyInjection\ContainerInterface as OldContainerInterface;
  50. use Plugin\StripeRec42\Service\Method\StripeRecurringNagMethod;
  51. //カスタマイズ開始
  52. use Customize\Controller\CustomizeShoppingController;
  53. use Plugin\StripePaymentGateway42\Service\Method\StripeCreditCard;
  54. use Plugin\StripePaymentGateway42\Service\Method\StripeKonbini;
  55. use Plugin\PayPalCheckout42\Service\Method\CreditCard;
  56. use Eccube\Service\Payment\Method\Cash;
  57. //class ShoppingExController extends ShoppingController
  58. class ShoppingExController extends CustomizeShoppingController
  59. //カスタマイズ終了
  60. {
  61.     private $stripe_config;    
  62.     protected $util_service;
  63.     protected $session;
  64.     protected $stripeCustomerRepository;
  65.     protected $eccubeConfig;
  66.     protected $config_service;
  67.     protected $rec_service;
  68.     protected $coupon_service;
  69.     protected $pb_service;
  70.     protected $stripeRecurringPaymentMethod;
  71.     protected $locale;
  72.     public function __construct(
  73.         ContainerInterface $serviceContainer,
  74.         UtilService $util_service,
  75.         EntityManagerInterface $entityManager,
  76.         ConfigService $config_service,
  77.         RecurringService $rec_service,
  78.         CouponService $coupon_service,
  79.         PointBundleService $pb_service,
  80.         StripeRecurringNagMethod $stripeRecurringNagMethod,
  81.         CartService $cartService,
  82.         MailService $mailService,
  83.         OrderRepository $orderRepository,
  84.         OrderHelper $orderHelper,
  85.         TradeLawRepository $tradeLawRepository,
  86.         RateLimiterFactory $shoppingConfirmIpLimiter,
  87.         RateLimiterFactory $shoppingConfirmCustomerLimiter,
  88.         RateLimiterFactory $shoppingCheckoutIpLimiter,
  89.         RateLimiterFactory $shoppingCheckoutCustomerLimiter,
  90.         BaseInfoRepository $baseInfoRepository,
  91.         ?ContainerInterface $oldContainer=null,
  92. //カスタマイズ開始
  93.     StripeCreditCard $stripeCreditCard// ←★追加
  94.     StripeKonbini $stripeKonbini// ←★追加
  95.     CreditCard $paypalCreditCard,
  96.     Cash $cashPayment
  97. //カスタマイズ終了
  98.     ) {
  99.         $this->util_service $util_service;
  100.         $this->entityManager $entityManager;
  101.         $this->stripeCustomerRepository $this->entityManager->getRepository(StripeCustomer::class);
  102.         $this->config_service $config_service;
  103.         $this->rec_service $rec_service;
  104.         $this->coupon_service $coupon_service;
  105.         $this->pb_service $pb_service;
  106.         $this->stripeRecurringPaymentMethod $stripeRecurringNagMethod;
  107.         $this->locale env('ECCUBE_LOCALE''ja');
  108.         if(version_compare(Constant::VERSION,'4.3.0','>=')) {
  109.             parent::__construct(
  110.                 $cartService,
  111.                 $mailService,
  112.                 $orderRepository,
  113.                 $orderHelper,
  114.                 $serviceContainer,
  115.                 $tradeLawRepository,
  116.                 $shoppingConfirmIpLimiter,
  117.                 $shoppingConfirmCustomerLimiter,
  118.                 $shoppingCheckoutIpLimiter,
  119.                 $shoppingCheckoutCustomerLimiter,
  120.                 $baseInfoRepository,
  121. //カスタマイズ開始
  122.         $stripeCreditCard// ←★追加
  123.         $stripeKonbini// ←★追加
  124.         $paypalCreditCard,
  125.         $cashPayment
  126. //カスタマイズ終了
  127.             );
  128.         } else {
  129.             parent::__construct(
  130.                 $cartService,
  131.                 $mailService,
  132.                 $orderRepository,
  133.                 $orderHelper,
  134.                 $oldContainer->get('service_container'),
  135.                 $tradeLawRepository,
  136.                 $shoppingConfirmIpLimiter,
  137.                 $shoppingConfirmCustomerLimiter,
  138.                 $shoppingCheckoutIpLimiter,
  139.                 $shoppingCheckoutCustomerLimiter,
  140.                 $baseInfoRepository,
  141. //カスタマイズ開始
  142.         $stripeCreditCard// ←★追加
  143.         $stripeKonbini// ←★追加
  144.         $paypalCreditCard,
  145.         $cashPayment
  146. //カスタマイズ終了
  147.             );
  148.         }
  149.     }
  150.     /**
  151.      * @Route("/plugin/StripeRec42/presubscribe", name="plugin_striperec_presubscripe")
  152.      */
  153.     public function presubscribe(Request $request)
  154.     {
  155. //        $StripeConfig = $this->stripeConfigRepository->get();
  156.         $preOrderId $this->cartService->getPreOrderId();
  157.         /** @var Order $Order */
  158.         $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  159.         if (!$Order) {
  160.             return $this->json(['error' => 'true''message' => trans('stripe_payment_gateway.admin.order.invalid_request')]);
  161.         }
  162.         $StripeConfig $this->entityManager->getRepository(StripeConfig::class)->getConfigByOrder($Order);
  163.         $stripeClient = new StripeClient($StripeConfig->secret_key);
  164.         $paymentMethodId $request->get('payment_method_id');
  165.         $stripeCustomerId $this->procStripeCustomer($stripeClient$Ordertrue);
  166.         if(is_array($stripeCustomerId)) { // エラー
  167.             return $this->json($stripeCustomerId);
  168.         }
  169.         
  170.         if($Order->hasStripePriceId()){
  171.             $this->session->getFlashBag()->set("stripe_customer_id"$stripeCustomerId);
  172.             $this->session->getFlashBag()->set("payment_method_id"$paymentMethodId);
  173.             return $this->json(["success" => true]);
  174.         }else {
  175.             return $this->json(["error" => "Not Recurring Product"]);
  176.         }
  177.     }
  178.     /**
  179.      * @Route("/plugin/StripeRec42/create_subscription_intent", name="plugin_striperec_create_subscription_intent")
  180.      */
  181.     public function createSubscriptionIntent(Request $request)
  182.     {
  183.         $preOrderId $this->cartService->getPreOrderId();
  184.         /** @var Order $Order */
  185.         $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  186.         if (!$Order) {
  187.             return $this->json([
  188.                 'error' => true,
  189.                 'message' => trans('stripe_payment_gateway.admin.order.invalid_request'),
  190.             ]);
  191.         }
  192.         if (!$Order->hasStripePriceId()) {
  193.             return $this->json([
  194.                 'error' => true,
  195.                 'message' => 'Not Recurring Product',
  196.             ]);
  197.         }
  198.         $StripeConfig $this->entityManager
  199.             ->getRepository(StripeConfig::class)
  200.             ->getConfigByOrder($Order);
  201.         \Stripe\Stripe::setApiKey($StripeConfig->secret_key);
  202.         $paymentMethodId $request->request->get('payment_method_id');
  203.         if (empty($paymentMethodId)) {
  204.             return $this->json([
  205.                 'error' => true,
  206.                 'message' => 'payment_method_id is required',
  207.             ]);
  208.         }
  209.         $stripeClient = new StripeClient($StripeConfig->secret_key);
  210.         $stripeCustomerId $this->procStripeCustomer($stripeClient$Ordertrue);
  211.         if (is_array($stripeCustomerId)) {
  212.             return $this->json($stripeCustomerId);
  213.         }
  214.         try {
  215.             // PaymentMethod を Customer に紐付け
  216.             $paymentMethod \Stripe\PaymentMethod::retrieve($paymentMethodId);
  217.             $paymentMethod->attach([
  218.                 'customer' => $stripeCustomerId,
  219.             ]);
  220.             // Customer のデフォルト支払い方法を更新
  221.             \Stripe\Customer::update($stripeCustomerId, [
  222.                 'invoice_settings' => [
  223.                     'default_payment_method' => $paymentMethodId,
  224.                 ],
  225.             ]);
  226.             // subscription items 作成
  227.             $orderItems $Order->getProductOrderItems();
  228.             $subscriptionItemsPre = [];
  229.             $subscriptionItems = [];
  230.             foreach ($orderItems as $orderItem) {
  231.                 $pc $orderItem->getProductClass();
  232.                 if (empty($pc) || !$pc->isRegistered()) {
  233.                     return $this->json([
  234.                         'error' => true,
  235.                         'message' => 'Recurring product is invalid',
  236.                     ]);
  237.                 }
  238.                 if (empty($subscriptionItemsPre[$pc->getStripePriceId()])) {
  239.                     $subscriptionItemsPre[$pc->getStripePriceId()] = [
  240.                         'price' => $pc->getStripePriceId(),
  241.                         'quantity' => $orderItem->getQuantity(),
  242.                     ];
  243.                 } else {
  244.                     $subscriptionItemsPre[$pc->getStripePriceId()]['quantity'] += $orderItem->getQuantity();
  245.                 }
  246.             }
  247.             foreach ($subscriptionItemsPre as $item) {
  248.                 $subscriptionItems[] = $item;
  249.             }
  250.             // クーポン対応
  251.             $couponId $request->request->get('coupon_id');
  252.             $subscriptionData = [
  253.                 'customer' => $stripeCustomerId,
  254.                 'items' => $subscriptionItems,
  255.                 'default_payment_method' => $paymentMethodId,
  256.                 'payment_behavior' => 'default_incomplete',
  257.                 'payment_settings' => [
  258.                     'save_default_payment_method' => 'on_subscription',
  259.                 ],
  260.                 'expand' => ['latest_invoice.payment_intent'],
  261.             ];
  262.             if (!empty($couponId)) {
  263.                 $subscriptionData['coupon'] = $couponId;
  264.             }
  265.             $subscription \Stripe\Subscription::create($subscriptionData);
  266.             $stripeOrder $this->entityManager->getRepository(StripeRecOrder::class)->findOneBy([
  267.                 'subscription_id'    => $subscription->id,
  268.                 'stripe_customer_id' => $stripeCustomerId,
  269.             ]);
  270.             if (empty($stripeOrder)) {
  271.                 $stripeOrder = new StripeRecOrder();
  272.             }
  273.             $stripeOrder->copyFrom($subscription);
  274.             $stripeOrder->setOrder($Order);
  275.             $stripeOrder->setStripeCustomerId($stripeCustomerId);
  276.             $stripeOrder->setCustomer($Order->getCustomer());
  277.             $stripeOrder->setSubscriptionId($subscription->id);
  278.             if (empty($stripeOrder->getRecStatus())) {
  279.                 $stripeOrder->setRecStatus(StripeRecOrder::REC_STATUS_SCHEDULED);
  280.             }
  281.             if (empty($stripeOrder->getPaidStatus())) {
  282.                 $stripeOrder->setPaidStatus(StripeRecOrder::STATUS_PAY_UNDEFINED);
  283.             }
  284.             if (empty($stripeOrder->getStartDate())) {
  285.                 $stripeOrder->setStartDate(new \DateTime());
  286.             }
  287.             $this->entityManager->persist($stripeOrder);
  288.             $Order->setRecOrder($stripeOrder);
  289.             $this->entityManager->persist($Order);
  290.             $this->entityManager->flush();
  291.             log_info('[REC_DEBUG][PRECREATE_REC_ORDER] rec_order_id=' $stripeOrder->getId());
  292.             log_info('[REC_DEBUG][PRECREATE_REC_ORDER] order_id=' $Order->getId());
  293.             log_info('[REC_DEBUG][PRECREATE_REC_ORDER] subscription_id=' $subscription->id);
  294.             $paymentIntent null;
  295.             if (
  296.                 isset($subscription->latest_invoice) &&
  297.                 isset($subscription->latest_invoice->payment_intent)
  298.             ) {
  299.                 $paymentIntent $subscription->latest_invoice->payment_intent;
  300.             }
  301. log_info('[REC_DEBUG][CREATE_SUB_INTENT] subscription_id=' $subscription->id);
  302. log_info('[REC_DEBUG][CREATE_SUB_INTENT] customer_id=' $stripeCustomerId);
  303. log_info('[REC_DEBUG][CREATE_SUB_INTENT] payment_intent_status=' . ($paymentIntent $paymentIntent->status 'NULL'));
  304. log_info('[REC_DEBUG][CREATE_SUB_INTENT] payment_intent_id=' . ($paymentIntent $paymentIntent->id 'NULL'));
  305.             if (!$paymentIntent) {
  306.                 return $this->json([
  307.                     'error' => true,
  308.                     'message' => trans('stripe_payment_gateway.front.unexpected_error'),
  309.                 ]);
  310.             }
  311.             // 後続 checkout 用に session / flash へ保存
  312.             $this->session->getFlashBag()->set('stripe_customer_id'$stripeCustomerId);
  313.             $this->session->getFlashBag()->set('payment_method_id'$paymentMethodId);
  314.             $this->session->getFlashBag()->set('precreated_subscription_id'$subscription->id);
  315.             // coupon も checkout 時に使えるよう保存
  316.             if (!empty($couponId)) {
  317.                 $this->session->set('stripe_rec_coupon_id'$couponId);
  318.             } else {
  319.                 $this->session->remove('stripe_rec_coupon_id');
  320.             }
  321.             switch ($paymentIntent->status) {
  322.                 case 'requires_confirmation':
  323.                 case 'requires_action':
  324.                 case 'requires_source_action':
  325.                     return $this->json([
  326.                         'action' => 'requires_action',
  327.                         'payment_intent_id' => $paymentIntent->id,
  328.                         'client_secret' => $paymentIntent->client_secret,
  329.                         'subscription_id' => $subscription->id,
  330.                     ]);
  331.                 case 'succeeded':
  332.                 case 'processing':
  333.                 case 'requires_capture':
  334.                     return $this->json([
  335.                         'action' => 'complete',
  336.                         'payment_intent_id' => $paymentIntent->id,
  337.                         'subscription_id' => $subscription->id,
  338.                     ]);
  339.                 case 'requires_payment_method':
  340.                 case 'requires_source':
  341.                     return $this->json([
  342.                         'error' => true,
  343.                         'message' => StripeClient::getErrorMessageFromCode('invalid_number'$this->locale),
  344.                     ]);
  345.                 default:
  346.                     return $this->json([
  347.                         'error' => true,
  348.                         'message' => 'Unexpected subscription payment intent status: '.$paymentIntent->status,
  349.                     ]);
  350.             }
  351.         } catch (\Exception $e) {
  352.             log_error('[StripeRec createSubscriptionIntent] '.$e->getMessage());
  353.             return $this->json([
  354.                 'error' => true,
  355.                 'message' => trans('stripe_payment_gateway.front.unexpected_error'),
  356.             ]);
  357.         }
  358.     }
  359.     /**
  360.      * @Route("/plugin/stripe_rec/success", name="plugin_stripe_rec_success")
  361.      */
  362.     public function success(Request $request){
  363.         $this->cartService->clear();
  364.         return $this->redirectToRoute("shopping_complete");
  365.     }
  366.     /**
  367.      * @Route("/plugin/stripe_rec/extra_payemnt/{id}/{stamp}", name="plugin_stripe_rec_extra_pay")
  368.      * @Template("@StripeRec42/default/Shopping/checkout_recurring_extra.twig")
  369.      */
  370.     public function extraPay(Request $request$id$stamp
  371.         StripeRecOrderRepository $recOrderRepository
  372.         StripeConfigRepository $stripeConfigRepository,
  373.         MailExService $mail_service)
  374.     {
  375.         $recOrder $recOrderRepository->find($id);
  376.         if (!$recOrder) {
  377.             throw new NotFoundHttpException();
  378.         }
  379.         if ($recOrder->getManualLinkStamp() != $stamp) {
  380.             throw new NotFoundHttpException();
  381.         }
  382.         $stripeConfig $stripeConfigRepository->getConfigByOrder($recOrder->getOrder());
  383.         $already $this->orderRepository->findOneBy(['recOrder' => $recOrder'manual_link_stamp' => $stamp]);
  384.         if ($already) {
  385.             return [
  386.                 'amount'    => 0
  387.                 'recOrder'  => $recOrder,
  388.                 'stripeConfig'=> $stripeConfig,
  389.                 'already_paid'=> true
  390.             ];
  391.         }
  392.         $details $this->rec_service->getPriceDetail($recOrder);
  393.         extract($details);
  394.         if ($recOrder->getPaymentCount() == 0) {
  395.             // 'bundle_order_items', 'initial_amount', 'recurring_amount', 'initial_discount', 'recurring_discount'
  396.             $amount $initial_amount $initial_discount;
  397.         } else {
  398.             $amount $recurring_amount $recurring_discount;
  399.         }
  400.         
  401.         $stripeClient = new StripeClient($stripeConfig->secret_key);
  402.         if ($request->getMethod() === "POST") {
  403.             $payment_intent_id $request->request->get('payment_intent_id');
  404.             if (empty($payment_intent_id)) {
  405.                 throw new NotFoundHttpException();
  406.             }
  407.             $is_auth_capture $stripeConfig->is_auth_and_capture_on;
  408.             log_info("----extra_pay---");
  409.             if ($is_auth_capture) {//Capture if on
  410.                 log_info("capturing payment, payment_intent_id : $payment_intent_id");
  411.                 $payment_intent $stripeClient->capturePaymentIntent($payment_intent_id$amount$recOrder->getOrder()->getCurrencyCode());
  412.                 log_info("captured payment, payment_intent_id : $payment_intent_id");
  413.             } else {
  414.                 $payment_intent $stripeClient->retrievePaymentIntent($payment_intent_id);
  415.             }
  416.             if (is_array($payment_intent) && isset($payment_intent['error'])) {
  417.                 $errorMessage StripeClient::getErrorMessageFromCode($payment_intent['error'], $this->locale);
  418.                 return $this->json(['error' =>  $errorMessage]);
  419.             }
  420.             if ($is_auth_capture) {
  421.                 $status_id OrderStatus::PAID;
  422.             } else {
  423.                 $status_id OrderStatus::NEW;
  424.             }
  425.             $NewOrder $this->rec_service->createNewOrder($recOrder$status_id);
  426.             $NewOrder->setManualLinkStamp($stamp);
  427.             $this->entityManager->persist($NewOrder);
  428.             $recOrder->setLastChargeId($payment_intent->charges->data[0]->id);
  429.             $recOrder->setPaidStatus(StripeRecOrder::STATUS_PAID);
  430.             $recOrder->setLastPaymentDate(new \DateTime());
  431.             $this->entityManager->persist($recOrder);
  432.             $this->entityManager->flush();
  433.             $recOrder->setCurrentPaymentTotal($amount);
  434.             $mail_service->sendPaidMail($recOrder);
  435.             return $this->json(['success' => true'order_id' => $NewOrder->getId()]);
  436.         }
  437.         return compact('amount''recOrder''stripeConfig');
  438.     }
  439.     /**
  440.      * @Route("/plugin/stripe_rec/extra_payment/intent/{id}", name="plugin_stripe_rec_extra_pay_intent")
  441.      */
  442.     public function extraPayIntent(Request $request$idStripeConfigRepository $stripeConfigRepository)
  443.     {
  444.         $rec_order $this->entityManager->getRepository(StripeRecOrder::class)->find($id);
  445.         if (!$rec_order) {
  446.             throw new NotFoundHttpException();
  447.         }
  448.         $Order $rec_order->getOrder();
  449.         $StripeConfig $stripeConfigRepository->getConfigByOrder($Order);
  450.         $stripeClient = new StripeClient($StripeConfig->secret_key);
  451.         
  452.         $paymentMethodId $request->request->get('payment_method_id');
  453.         $isSaveCardOn $request->request->get('is_save_on') === "true" true false;
  454.         $stripeCustomerId $this->procStripeCustomer($stripeClient$Order$isSaveCardOn);
  455.         if (is_array($stripeCustomerId)) {
  456.             return $this->json($stripeCustomerId);
  457.         }
  458.         $details $this->rec_service->getPriceDetail($rec_order);
  459.         extract($details);
  460.         if ($rec_order->getPaymentCount() == 0) {
  461.             // 'bundle_order_items', 'initial_amount', 'recurring_amount', 'initial_discount', 'recurring_discount'
  462.             $amount $initial_amount $initial_discount;
  463.         } else {
  464.             $amount $recurring_amount $recurring_discount;
  465.         }
  466.         $paymentIntent $stripeClient->createPaymentIntentWithCustomer(
  467.             $amount
  468.             $paymentMethodId
  469.             $Order->getId(), 
  470.             $isSaveCardOn
  471.             $stripeCustomerId,
  472.             $Order->getCurrencyCode());
  473.         return $this->json($this->genPaymentResponse($paymentIntent));
  474.     }
  475.     /**
  476.      * @Route("/plugin/stripe_rec/cancel", name="plugin_stripe_rec_cancel")
  477.      */
  478.     public function cancel(Request $request){
  479.         $preOrderId $this->cartService->getPreOrderId();
  480.         $order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  481.         if(empty($order)){
  482.             return $this->redirectToRoute("shopping");
  483.         }
  484.         if(!$order->isRecurring()){
  485.             return $this->redirectToRoute("shopping");
  486.         }
  487.         $rec_order $order->getRecOrder();
  488.         $rec_items  $rec_order->getOrderItems();
  489.         foreach($rec_items as $rec_item){
  490.             $this->entityManager->remove($rec_item);
  491.             $this->entityManager->flush();
  492.             $this->entityManager->commit();
  493.         }
  494.         
  495.         $this->entityManager->remove($rec_order);
  496.         $this->entityManager->flush();
  497.         $this->entityManager->commit();
  498.         
  499.         return $this->redirectToRoute("shopping");
  500.     }
  501.     /**
  502.      * @Route("/plugin/stripe_rec/checkout_page", name="plugin_striperec_checkout_page")
  503.      * @Template("@StripeRec42/default/Shopping/checkout.twig")
  504.      */
  505.     public function credit_payment(Request $request)
  506.     {
  507.         // ログイン状態のチェック.
  508.         if ($this->orderHelper->isLoginRequired()) {
  509.             log_info('[注文処理] 未ログインもしくはRememberMeログインのため, ログイン画面に遷移します.');
  510.             return $this->redirectToRoute('shopping_login');
  511.         }
  512.         // 受注の存在チェック
  513.         $preOrderId $this->cartService->getPreOrderId();
  514.         $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  515.         if (!$Order) {
  516.             log_info('[注文処理] 購入処理中の受注が存在しません.', [$preOrderId]);
  517.             
  518.             return $this->redirectToRoute('shopping_error');
  519.         }
  520.         $StripeConfig $this->entityManager->getRepository(StripeConfig::class)->getConfigByOrder($Order);
  521.         
  522.         $Customer $Order->getCustomer();
  523.         // フォームの生成.
  524.         $form $this->createForm(OrderType::class, $Order,[
  525.             'skip_add_form' =>  true,
  526.         ]);
  527.         $form->handleRequest($request);
  528.         $checkout_ga_enable $StripeConfig->checkout_ga_enable;
  529.         
  530.         $rec_config $this->config_service->getConfig();
  531.         $coupon_enable $rec_config[ConfigService::COUPON_ENABLE];
  532.         if ($form->isSubmitted() && $form->isValid()) {
  533.             return [
  534.                 'stripeConfig'  =>  $StripeConfig,
  535.                 'Order'         =>  $Order,
  536.                 'checkout_ga_enable' => $checkout_ga_enable,
  537.                 'coupon_enable' =>  $coupon_enable,
  538.             ];
  539.         }
  540.         return $this->redirectToRoute('shopping');
  541.     }
  542.     /**
  543.      * @Route("/plugin/stripe_rec/check_coupon", name="plugin_striperec_coupon_check")
  544.      */
  545.     public function checkCoupon(Request $request){
  546.         $coupon_id $request->request->get('coupon_id');
  547.         $res $this->coupon_service->retrieveCoupon($coupon_id);
  548.         if(empty($res)){
  549.             return $this->json([
  550.                 'error' =>  true,
  551.                 'message'   =>  $this->coupon_service->getError()
  552.             ]);
  553.         }
  554.         if(empty($res->valid)){
  555.             return $this->json([
  556.                 'error' =>  true,
  557.                 'message'   =>  trans("stripe_recurring.coupon.error.expired_or_invalid")
  558.             ]);
  559.         }
  560.         $Order $this->getOrder();
  561.         
  562.         $bundle_include_arr $this->session->get('bundle_include_arr');
  563.         $bundles $this->pb_service->getBundleProducts($Order$bundle_include_arr);
  564.         
  565.         $price_sum $this->pb_service->getPriceSum($Order);
  566.         extract($price_sum);
  567.         if($bundles){
  568.             $bundle_order_items $bundles['order_items'];
  569.             $initial_amount += $bundles['price'];
  570.         }else{
  571.             $bundle_order_items null;
  572.         }
  573.         $initial_discount $this->coupon_service->couponDiscountAmount($initial_amount$res);
  574.         $recurring_discount $this->coupon_service->couponDiscountAmount($recurring_amount$res);
  575.         
  576.         return $this->json([
  577.             'success'   =>  true,
  578.             'initial_amount'    =>  $initial_amount,
  579.             'recurring_amount'  =>  $recurring_amount,
  580.             'initial_discount'  =>  $initial_discount,
  581.             'recurring_discount'=>  $recurring_discount,
  582.         ]);
  583.     }
  584.     /**
  585.      * @Route("/plugin/striperec/checkout", name="plugin_striperec_checkout")
  586.      */
  587.     public function checkout(Request $request){
  588.         $Order $this->getOrder();
  589.         if (!$Order) {
  590.             $this->addError(trans('stripe_payment_gateway.admin.order.invalid_request'));
  591.             return $this->redirectToRoute('shopping_error');
  592.         }
  593.         
  594.         // EOC validation checking
  595.         try {
  596.             $response $this->executePurchaseFlow($Order);
  597.             $this->entityManager->flush();
  598.             if ($response) {
  599.                 return $response;
  600.             }
  601.             log_info('[注文処理] PaymentMethodを取得します.', [$Order->getPayment()->getMethodClass()]);
  602.             $paymentMethod $this->createPaymentMethod($Ordernull);
  603.             /*
  604.                 * 決済実行(前処理)
  605.                 */
  606.             log_info('[注文処理] PaymentMethod::applyを実行します.');
  607.             if ($response $this->executeApply($paymentMethod)) {
  608.                 return $response;
  609.             }
  610.             /*
  611.             * 決済実行
  612.             *
  613.             * PaymentMethod::checkoutでは決済処理が行われ, 正常に処理出来た場合はPurchaseFlow::commitがコールされます.
  614.             */
  615.             log_info('[注文処理] PaymentMethod::checkoutを実行します.');
  616.             if ($response $this->executeCheckout($paymentMethod)) {
  617.                 return $response;
  618.             }
  619.             $this->entityManager->flush();
  620.             log_info('[注文処理] 注文処理が完了しました.', [$Order->getId()]);
  621.         }catch (ShoppingException $e) {
  622.             log_error('[注文処理] 購入エラーが発生しました.', [$e->getMessage()]);
  623.             $this->entityManager->rollback();
  624.             $this->addError($e->getMessage());
  625.             return $this->redirectToRoute('shopping_error');
  626.         } catch (\Exception $e) {
  627.             log_error('[注文処理] 予期しないエラーが発生しました.', [$e->getMessage()]);
  628.             $this->entityManager->rollback();
  629.             $this->addError('front.shopping.system_error');
  630.             return $this->redirectToRoute('shopping_error');
  631.         }
  632.         // カート削除
  633.         log_info('[注文処理] カートをクリアします.', [$Order->getId()]);
  634.         $this->cartService->clear();
  635.         // 受注IDをセッションにセット
  636.         $this->session->set(OrderHelper::SESSION_ORDER_ID$Order->getId());
  637.         // メール送信
  638.         log_info('[注文処理] 注文メールの送信を行います.', [$Order->getId()]);
  639.         $this->mailService->sendOrderMail($Order);
  640.         $this->entityManager->flush();
  641.         log_info('[注文処理] 注文処理が完了しました. 購入完了画面へ遷移します.', [$Order->getId()]);
  642.         return $this->redirectToRoute('shopping_complete');
  643.     }
  644.     // For original card input recurring
  645.     private function procStripeCustomer(StripeClient $stripeClient$Order$isSaveCardOn) {
  646.         $Customer $Order->getCustomer();
  647.         $isEcCustomer=false;
  648.         $isStripeCustomer=false;
  649.         $StripeCustomer false;
  650.         $stripeCustomerId false;
  651.         if($Customer instanceof Customer ){
  652.             $isEcCustomer=true;
  653.             $StripeCustomer=$this->stripeCustomerRepository->findOneBy(array('Customer'=>$Customer));
  654.             if($StripeCustomer instanceof StripeCustomer){
  655.                 $stripLibCustomer $stripeClient->retrieveCustomer($StripeCustomer->getStripeCustomerId());
  656.                 if(is_array($stripLibCustomer) || isset($stripLibCustomer['error'])) {
  657.                     if(isset($stripLibCustomer['error']['code']) && $stripLibCustomer['error']['code'] == 'resource_missing') {
  658.                         $isStripeCustomer false;
  659.                     }
  660.                 } else {
  661.                     $isStripeCustomer=true;
  662.                 }
  663.             }
  664.         }
  665.         if($isEcCustomer) {//Create/Update customer
  666.             if($isSaveCardOn) {
  667.                 //BOC check if is StripeCustomer then update else create one
  668.                 if($isStripeCustomer) {
  669.                     $stripeCustomerId=$StripeCustomer->getStripeCustomerId();
  670.                     //BOC save is save card
  671.                     $StripeCustomer->setIsSaveCardOn($isSaveCardOn);
  672.                     $this->entityManager->persist($StripeCustomer);
  673.                     $this->entityManager->flush($StripeCustomer);
  674.                     //EOC save is save card
  675.                     $updateCustomerStatus $stripeClient->updateCustomerV2($stripeCustomerId,$Customer->getEmail());
  676.                     if (is_array($updateCustomerStatus) && isset($updateCustomerStatus['error'])) {//In case of update fail
  677.                         $errorMessage=StripeClient::getErrorMessageFromCode($updateCustomerStatus['error'], $this->locale);
  678.                         return ['error' => true'message' => $errorMessage];
  679.                     }
  680.                 } else {
  681.                     $stripeCustomerId=$stripeClient->createCustomerV2($Customer->getEmail(),$Customer->getId());
  682.                     if (is_array($stripeCustomerId) && isset($stripeCustomerId['error'])) {//In case of fail
  683.                         $errorMessage=StripeClient::getErrorMessageFromCode($stripeCustomerId['error'], $this->locale);
  684.                         return ['error' => true'message' => $errorMessage];
  685.                     } else {
  686.                         if(!$StripeCustomer) {
  687.                             $StripeCustomer = new StripeCustomer();
  688.                             $StripeCustomer->setCustomer($Customer);
  689.                         }
  690.                         $StripeCustomer->setStripeCustomerId($stripeCustomerId);
  691.                         $StripeCustomer->setIsSaveCardOn($isSaveCardOn);
  692.                         $StripeCustomer->setCreatedAt(new \DateTime());
  693.                         $this->entityManager->persist($StripeCustomer);
  694.                         $this->entityManager->flush($StripeCustomer);
  695.                     }
  696.                 }
  697.                 //EOC check if is StripeCustomer then update else create one
  698.                 return $stripeCustomerId;
  699.             }
  700.         }
  701.         //Create temp customer
  702.         $stripeCustomerId=$stripeClient->createCustomerV2($Order->getEmail(),0,$Order->getId());
  703.         if (is_array($stripeCustomerId) && isset($stripeCustomerId['error'])) {//In case of fail
  704.             $errorMessage=StripeClient::getErrorMessageFromCode($stripeCustomerId['error'], $this->locale);
  705.             return ['error' => true'message' => $errorMessage];
  706.         }
  707.         return $stripeCustomerId;
  708.     }
  709.     private function getErrorMessages(\Symfony\Component\Form\Form $form) {
  710.         $errors = array();
  711.     
  712.         foreach ($form->getErrors() as $key => $error) {
  713.             if ($form->isRoot()) {
  714.                 $errors['#'][] = $error->getMessage();
  715.             } else {
  716.                 $errors[] = $error->getMessage();
  717.             }
  718.         }
  719.     
  720.         foreach ($form->all() as $child) {
  721.             if (!$child->isValid()) {
  722.                 $errors[$child->getName()] = $this->getErrorMessages($child);
  723.             }
  724.         }
  725.     
  726.         return $errors;
  727.     }
  728.     private function getOrder(){
  729.         // BOC validation checking
  730.         $preOrderId $this->cartService->getPreOrderId();
  731.         /** @var Order $Order */
  732.         return $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  733.    }
  734.    /**
  735.      * PaymentMethodをコンテナから取得する.
  736.      *
  737.      * @param Order $Order
  738.      * @param FormInterface $form
  739.      *
  740.      * @return PaymentMethodInterface
  741.      */
  742.     private function createPaymentMethod(Order $Order)
  743.     {
  744.         $PaymentMethod $this->serviceContainer->get($Order->getPayment()->getMethodClass());
  745.         //$PaymentMethod = $this->stripeRecurringPaymentMethod;
  746.         $PaymentMethod->setOrder($Order);
  747.         return $PaymentMethod;
  748.     }
  749.     private function genPaymentResponse($intent) {
  750.         if($intent instanceof PaymentIntent ) {
  751.             log_info("genPaymentResponse: " $intent->status);
  752.             switch($intent->status) {
  753.                 case 'requires_action':
  754.                 case 'requires_source_action':
  755.                     return [
  756.                         'action'=> 'requires_action',
  757.                         'payment_intent_id'=> $intent->id,
  758.                         'client_secret'=> $intent->client_secret
  759.                     ];
  760.                 case 'requires_payment_method':
  761.                 case 'requires_source':
  762.                     return [
  763.                         'error' => true,
  764.                         'message' => StripeClient::getErrorMessageFromCode('invalid_number'$this->locale)
  765.                     ];
  766.                 case 'requires_capture':
  767.                     return [
  768.                         'action' => 'requires_capture',
  769.                         'payment_intent_id' => $intent->id
  770.                     ];
  771.                 default:
  772.                     return ['error' => true'message' => trans('stripe_payment_gateway.front.unexpected_error')];
  773. //                    return ['error' => true, 'message' => trans('stripe_payment_gateway.front.unexpected_error')];
  774.             }
  775.         }
  776.         if(isset($intent['error'])) {
  777.             $errorMessage=StripeClient::getErrorMessageFromCode($intent['error'], $this->locale);
  778.         } else {
  779.             $errorMessage trans('stripe_payment_gateway.front.unexpected_error');
  780.         }
  781.         return ['error' => true'message' => $errorMessage];
  782.     }
  783. }