Snippets

Joshua WIlkeson My Recurring Payments Code

Created by Joshua WIlkeson last modified
    /**
     * @Route("/accounts/order/paypal/completed", name="order_paypal_completed")
     */
    public function orderPaypalCompletedAction(Request $request)
    {
        $token = $this->get('payum')->getHttpRequestVerifier()->verify($request);
        $identity = $token->getDetails();
        $payment = $this->get('payum')->getStorage($identity->getClass())->find($identity);

        $gateway = $this->get('payum')->getGateway($token->getGatewayName());
        $gateway->execute($status = new GetHumanStatus($payment));

        $order = $payment->getOrder();

        if ($status->isCaptured() || $status->isAuthorized()) {
            $order->setStatus(Order::STATUS_COMPLETED);
            $this->addFlash('success', $this->get('translator')->trans('Payment has been successful.'));
        }

        if ($status->isPending()) {
            $this->addFlash('danger', $this->get('translator')->trans('Payment has been canceled.'));
        }

        if ($status->isFailed() || $status->isCanceled()) {
            $order->setStatus(Order::STATUS_CANCELED);
            $this->addFlash('danger', $this->get('translator')->trans('Payment has been canceled.'));
        }

        try {
        // And I have a postUpdate event listener for Doctrine that changes entities accordingly 
            $em = $this->getDoctrine()->getManager();
            $em->persist($order);
            $em->flush();
        } catch (\Exception $e) {
            $this->addFlash('danger', $this->get('translator')->trans('An error occurred when saving object.'));
        }
        return $this->redirectToRoute('order');
    }

    /**
     * @Route("/accounts/checkout", name="checkout")
     */
    public function checkoutAction(Request $request)
    {
        $orderForm = $this->createForm(OrderType::class, null, [
            'user' => $this->getUser(),
            'gateways' => $this->getParameter('app.gateways'),
        ]);
        $orderForm->handleRequest($request);
        $filter = $this->createForm(FilterHeroType::class, [], [
            'hierarchy_categories' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Category'), 'category', 'categories'),
            'router' => $this->get('router'),
        ]);

        // Calculate total price
        $products = $request->getSession()->get('products');
        if (!$products) {
            $this->addFlash('danger', $this->get('translator')->trans('Cart is empty. Not able to proceed checkout.'));

            return $this->redirectToRoute('cart');
        }

        $price = 0;
        foreach ($products as $product) {
            $price += $product['price'];
        }

        // Save order
        if ($orderForm->isSubmitted() && $orderForm->isValid()) {
            $order = $orderForm->getData();
            $order->setStatus(Order::STATUS_NEW);
            $order->setUser($this->getUser());
            $order->setCurrency($this->getParameter('app.currency'));
            $order->setPrice($price);

            try {
                $em = $this->getDoctrine()->getManager();
                $em->persist($order);
                $em->flush();
            } catch (\Exception $e) {
                $this->addFlash('danger', $this->get('translator')->trans('An error occurred whe saving order.'));
            }

            // Save order items
            foreach ($products as $product) {
                $orderItem = new OrderItem();
                if ($product['type'] == 'pay_for_featured' || $product['type'] == 'pay_for_publish') {
                    $listing = $this->getDoctrine()->getRepository('AppBundle:Listing')->findOneBy(['id' => $product['listing_id']]);
                    $orderItem->setListing($listing);
                } else {
                    $county = $this->getDoctrine()->getRepository('AppBundle:County')->findOneBy(['id' => $product['county_id']]);
                    $orderItem->setCounty($county);
                }

                $orderItem->setOrder($order);
                $orderItem->setPrice($product['price']);
                $orderItem->setType($product['type']);
                $orderItem->setDuration($product['duration']);

                try {
                    $em = $this->getDoctrine()->getManager();
                    $em->persist($orderItem);
                    $em->flush();
                } catch (\Exception $e) {
                    $this->addFlash('danger', $this->get('translator')->trans('An error occurred whe saving order item.'));
                }
            }

            $request->getSession()->remove('products');
            $this->addFlash('success', $this->get('translator')->trans('Order has been successfully saved.'));

            if ($order->getGateway() == 'paypal') {
                $gatewayName = 'paypal_express_checkout';

                $storage = $this->get('payum')->getStorage(Payment::class);

                $payment = $storage->create();
                $payment->setNumber(uniqid());
                $payment->setCurrencyCode($this->getParameter('app.currency'));
                $payment->setTotalAmount($price * 100);
                $payment->setDescription('A description');
                $payment->setClientId($this->getUser()->getId());
                $payment->setClientEmail('user-email@host.tld');
                $payment->setDescription('Payment for services rendered');
                $payment->setOrder($order);
                $payment->setDetails([
                  'L_BILLINGTYPE0' => Api::BILLINGTYPE_RECURRING_PAYMENTS,
                  'L_BILLINGAGREEMENTDESCRIPTION0' => "first item",
                ]);
                $storage->update($payment);

                $captureToken = $this->get('payum')->getTokenFactory()->createCaptureToken($gatewayName, $payment, 'order_paypal_completed');
                return $this->redirect($captureToken->getTargetUrl());
            }

            return $this->redirectToRoute('order');
        }

        return $this->render('FrontBundle::Order/checkout.html.twig', [
          'order' => $orderForm->createView(),
          'filter' => $filter->createView()
        ]);
    }

Comments (0)