currencyContext = $currencyContext; $this->countryContext = $countryContext; $this->logger = $logger; \Payment::includeClass('PayPalCheckout'); $this->payPalCheckout = new \PayPalCheckout(); $this->payPalCheckout->loadConfig(); } protected function createClient(): PayPalHttpClient { $config = $this->payPalCheckout->config; if (($config['mode'] ?? 'sandbox') === 'sandbox') { $environment = new SandboxEnvironment($config['clientID'], $config['secret']); } else { $environment = new ProductionEnvironment($config['clientID'], $config['secret']); } return new PayPalHttpClient($environment); } /** * @Route("/paypal-checkout/create-paypal-order/") * * @return Response */ public function createPayPalOrder(Request $request, \Cart $cart) { $cart->load(); $deliveryTypeID = $this->payPalCheckout->config['delivery_type_id']; $cart->setTransport($deliveryTypeID); // set street, email and country so cart does not break in case paypal fails $cart->updateAddresses( ['street' => 'street', 'email' => 'email@email.com'], ['country' => $this->countryContext->getActiveId()] ); $step = 'delivery'; $cart->findNextStep($step); $cart->actualStep = $step; $cart->save(); $cart->createFromDB(); // TODO: accept also hidden delivery type try { $inStoreError = $cart->checkCartItems(); } catch (\Exception $e) { $inStoreError = $e->getMessage(); } if (!empty($inStoreError)) { $response = ['error' => $inStoreError]; return new JsonResponse($response); } $price = number_format($cart->totalPricePay->asFloat(), 2, '.', ''); $data = [ 'intent' => 'CAPTURE', 'purchase_units' => [ [ 'amount' => [ 'currency_code' => $this->currencyContext->getActiveId(), 'value' => $price, ], ], ], ]; $request = new OrdersCreateRequest(); $request->prefer('return=representation'); $request->body = $data; $response = $this->createClient()->execute($request); return new JsonResponse($response); } /** * @Route("/paypal-checkout/capture-paypal-order/{paypalOrderID}/") * * @return Response */ public function capturePayPalOrder(string $paypalOrderID, Request $request, \Cart $cart) { $client = $this->createClient(); $cart->load(); $cart->createFromDB(); $orderGetResponse = $client->execute(new OrdersGetRequest($paypalOrderID)); if (($orderGetResponse->result->status ?? false) === 'APPROVED') { $address = $orderGetResponse->result->purchase_units[0]->shipping->address; $tmpLine1 = explode(' ', $address->address_line_1); $house = count($tmpLine1) > 1 ? array_pop($tmpLine1) : ''; $street = implode(' ', $tmpLine1); $invoice = [ 'email' => $orderGetResponse->result->payer->email_address, 'gender' => 'male', 'name' => $orderGetResponse->result->payer->name->given_name, 'surname' => $orderGetResponse->result->payer->name->surname, 'phone' => $orderGetResponse->result->payer->phone->phone_number ?? '', 'zip' => $address->postal_code, 'city' => $address->admin_area_2, 'street' => $street, 'house' => $house, 'country' => $address->country_code, ]; $invoice['phone'] = empty($invoice['phone']) ? '123456789' : $invoice['phone']; $delivery = $invoice; $delivery['street'] = $address->address_line_1; unset($delivery['email'], $delivery['gender']); $cart->updateAddresses($invoice, $delivery); $order = $cart->submitOrder(); if (!$order instanceof \Order) { $this->logger->captureMessage('PayPal Checkout: Failed to create kupshop order for PayPal order '.$paypalOrderID.': submitOrder() result '.json_encode($order)); addUserMessage('Failed to create order', 'danger'); redirection(createScriptURL(['s' => 'cart'])); } // create kupshop order payment $price = \Decimal::create($orderGetResponse->result->purchase_units[0]->amount->value); $this->payPalCheckout->setOrder($order); $this->payPalCheckout->createPayment($orderGetResponse->result->id, $price, [ 'PayPalCheckoutController' => true, 'result' => $orderGetResponse, ]); // capture paypal order $captureResponse = $client->execute(new OrdersCaptureRequest($paypalOrderID)); if (($captureResponse->result->status ?? false) === 'COMPLETED') { // capture succeeded if (!$this->payPalCheckout->setStatus(\Payment::STATUS_FINISHED, $orderGetResponse->result->id)) { $this->logger->captureMessage('setStatus failed!'); throw new \Exception('Set status failed'); } // redirect to order detail $this->payPalCheckout->success(translate('paymentSuccess', 'payment')); } // payment storno if (!$this->payPalCheckout->setStatus(\Payment::STATUS_STORNO, $orderGetResponse->result->id)) { $this->logger->captureMessage('setStatus failed!'); throw new \Exception('Set status failed'); } // redirect to order detail $this->payPalCheckout->error(translate('payment_storno', 'payment')); } $this->logger->captureMessage('PayPal Checkout: PayPal order '.$paypalOrderID.' not APPROVED!'); addUserMessage('Failed to create order', 'danger'); redirection(createScriptURL(['s' => 'cart'])); } }