gqlClient = $gqlClient; $this->tokenService = $tokenService; $this->productRepository = $productRepository; } /** * Place order for a bundled product * * @param array $customerLogin * @param array $productData * @param array|null $addressData * @return array */ public function placeOrderWithBundleProduct( array $customerLogin, array $productData, ?array $addressData = null ): array { $this->customerLogin = $customerLogin; $this->createCustomerCart(); $this->addBundleProduct($productData); $this->setBillingAddress($addressData); $shippingMethod = $this->setShippingAddress($addressData); $paymentMethod = $this->setShippingMethod($shippingMethod); $this->setPaymentMethod($paymentMethod); return $this->doPlaceOrder(); } /** * Make GraphQl POST request * * @param string $query * @param array $additionalHeaders * @return array */ private function makeRequest(string $query, array $additionalHeaders = []): array { $headers = array_merge([$this->getAuthHeader()], $additionalHeaders); return $this->gqlClient->post($query, [], '', $headers); } /** * Get header for authenticated requests * * @return string * @throws \Magento\Framework\Exception\AuthenticationException */ private function getAuthHeader(): string { if (empty($this->authHeader)) { $customerToken = $this->tokenService ->createCustomerAccessToken($this->customerLogin['email'], $this->customerLogin['password']); $this->authHeader = "Authorization: Bearer {$customerToken}"; } return $this->authHeader; } /** * Get cart id * * @return string */ private function getCartId(): string { if (empty($this->cartId)) { $this->cartId = $this->createCustomerCart(); } return $this->cartId; } /** * Create empty cart for the customer * * @return array */ private function createCustomerCart(): string { //Create empty cart $createEmptyCart = <<makeRequest($createEmptyCart); return $result['createEmptyCart']; } /** * Add a bundle product to the cart * * @param array $productData * @return array * @throws \Magento\Framework\Exception\NoSuchEntityException */ private function addBundleProduct(array $productData) { $productSku = $productData['sku']; $qty = $productData['quantity'] ?? 1; /** @var Product $bundleProduct */ $bundleProduct = $this->productRepository->get($productSku); /** @var \Magento\Bundle\Model\Product\Type $typeInstance */ $typeInstance = $bundleProduct->getTypeInstance(); $optionId1 = (int)$typeInstance->getOptionsCollection($bundleProduct)->getFirstItem()->getId(); $optionId2 = (int)$typeInstance->getOptionsCollection($bundleProduct)->getLastItem()->getId(); $selectionId1 = (int)$typeInstance->getSelectionsCollection([$optionId1], $bundleProduct) ->getFirstItem() ->getSelectionId(); $selectionId2 = (int)$typeInstance->getSelectionsCollection([$optionId2], $bundleProduct) ->getLastItem() ->getSelectionId(); $addProduct = <<getCartId()}" cart_items:[ { data:{ sku:"{$productSku}" quantity:{$qty} } bundle_options:[ { id:{$optionId1} quantity:1 value:["{$selectionId1}"] } { id:$optionId2 quantity:2 value:["{$selectionId2}"] } ] } ] }) { cart { items {quantity product {sku}} } } } QUERY; return $this->makeRequest($addProduct); } /** * Set the billing address on the cart * * @param array $addressData * @return array */ private function setBillingAddress(?array $addressData = null): array { $telephone = $addressData['telephone'] ?? '5123456677'; $setBillingAddress = <<getCartId()}" billing_address: { address: { firstname: "John" lastname: "Smith" company: "Test company" street: ["test street 1", "test street 2"] city: "Texas City" postcode: "78717" telephone: "{$telephone}" region: "TX" country_code: "US" } } } ) { cart { billing_address { __typename } } } } QUERY; return $this->makeRequest($setBillingAddress); } /** * Set the shipping address on the cart and return an available shipping method * * @param array|null $addressData * @return array */ private function setShippingAddress(?array $addressData): array { $telephone = $addressData['telephone'] ?? '5123456677'; $setShippingAddress = <<getCartId()}" shipping_addresses: [ { address: { firstname: "test shipFirst" lastname: "test shipLast" company: "test company" street: ["test street 1", "test street 2"] city: "Montgomery" region: "AL" postcode: "36013" country_code: "US" telephone: "{$telephone}" } } ] } ) { cart { shipping_addresses { available_shipping_methods { carrier_code method_code amount {value} } } } } } QUERY; $result = $this->makeRequest($setShippingAddress); $shippingMethod = $result['setShippingAddressesOnCart'] ['cart']['shipping_addresses'][0]['available_shipping_methods'][0]; return $shippingMethod; } /** * Set the shipping method on the cart and return an available payment method * * @param array|null $shippingMethod * @return array */ private function setShippingMethod(?array $shippingMethod): array { $setShippingMethod = <<getCartId()}", shipping_methods: [ { carrier_code: "{$shippingMethod['carrier_code']}" method_code: "{$shippingMethod['method_code']}" } ] }) { cart { available_payment_methods { code title } } } } QUERY; $result = $this->makeRequest($setShippingMethod); $paymentMethod = $result['setShippingMethodsOnCart']['cart']['available_payment_methods'][0]; return $paymentMethod; } /** * Set the payment method on the cart * * @param array $paymentMethod * @return array */ private function setPaymentMethod(array $paymentMethod): array { $setPaymentMethod = <<getCartId()}" payment_method: { code: "{$paymentMethod['code']}" } } ) { cart { selected_payment_method { code } } } } QUERY; return $this->makeRequest($setPaymentMethod); } /** * Place the order * * @return array */ private function doPlaceOrder(): array { $placeOrder = <<getCartId()}" } ) { order { order_number } } } QUERY; return $this->makeRequest($placeOrder); } }