/** * Returns the payment form for entering payment details at the shop site. * * @param \Aimeos\MShop\Order\Item\Iface $order Order object * @param array $params Request parameter if available * @return \Aimeos\MShop\Common\Item\Helper\Form\Iface Form helper object */ protected function getPaymentForm(\Aimeos\MShop\Order\Item\Iface $order, array $params) { $list = array(); $feConfig = $this->feConfig; $baseItem = $this->getOrderBase($order->getBaseId(), \Aimeos\MShop\Order\Manager\Base\Base::PARTS_ADDRESS); try { $address = $baseItem->getAddress(); if (!isset($params[$feConfig['payment.firstname']['internalcode']]) || $params[$feConfig['payment.firstname']['internalcode']] == '') { $feConfig['payment.firstname']['default'] = $address->getFirstname(); } if (!isset($params[$feConfig['payment.lastname']['internalcode']]) || $params[$feConfig['payment.lastname']['internalcode']] == '') { $feConfig['payment.lastname']['default'] = $address->getLastname(); } if ($this->getValue('address')) { $feConfig['payment.address1']['default'] = $address->getAddress1() . ' ' . $address->getAddress2(); $feConfig['payment.city']['default'] = $address->getCity(); $feConfig['payment.postal']['default'] = $address->getPostal(); $feConfig['payment.countryid']['default'] = $address->getCountryId(); $feConfig['payment.telephone']['default'] = $address->getTelephone(); $feConfig['payment.company']['default'] = $address->getCompany(); $feConfig['payment.email']['default'] = $address->getEmail(); } } catch (\Aimeos\MShop\Order\Exception $e) { } // If address isn't available foreach ($feConfig as $key => $config) { $list[$key] = new \Aimeos\MW\Criteria\Attribute\Standard($config); } $url = $this->getConfigValue(array('payment.url-self')); return new \Aimeos\MShop\Common\Item\Helper\Form\Standard($url, 'POST', $list, false); }
/** * Builds a complete XML string including the order data * * @param \Aimeos\MShop\Order\Item\Iface $invoice Order of the customer * @return string Validated XML string with order data * @throws \Aimeos\MShop\Service\Exception If an error occurs */ public function buildXML(\Aimeos\MShop\Order\Item\Iface $invoice) { $base = $this->getOrderBase($invoice->getBaseId(), \Aimeos\MShop\Order\Manager\Base\Base::PARTS_ALL); try { $dom = new \DOMDocument('1.0', 'UTF-8'); $orderlist = $dom->createElement('orderlist'); $orderitem = $dom->createElement('orderitem'); $this->buildXMLHeader($invoice, $base, $dom, $orderitem); $this->buildXMLService($base, $dom, $orderitem); $this->buildXMLPrice($base, $dom, $orderitem); $this->buildXMLProducts($base, $dom, $orderitem); $this->buildXMLAddresses($base, $dom, $orderitem); $this->buildXMLAdditional($base, $dom, $orderitem); $orderlist->appendChild($orderitem); $dom->appendChild($orderlist); } catch (\DOMException $e) { $msg = 'Creating XML file with order data for delivery provider failed: %1$s'; throw new \Aimeos\MShop\Service\Exception(sprintf($msg, $e->getMessage()), 0, $e); } $requestXSD = __DIR__ . DIRECTORY_SEPARATOR . 'xsd' . DIRECTORY_SEPARATOR . 'order-request_v1.xsd'; if ($dom->schemaValidate($requestXSD) !== true) { $msg = 'Validation of XML response from delivery provider against schema "%1$s" failed: %2$s'; throw new \Aimeos\MShop\Service\Exception(sprintf($msg, $requestXSD, $dom->saveXML()), parent::ERR_SCHEMA); } if (($xml = $dom->saveXML()) === false) { $msg = 'DOM tree of XML response from delivery provider could not be converted to XML string'; throw new \Aimeos\MShop\Service\Exception(sprintf($msg), parent::ERR_XML); } return $xml; }
/** * Adds the services from the given order item to the basket. * * @param \Aimeos\MShop\Order\Item\Base\Iface $order Basket object * @param \Aimeos\MShop\Order\Item\Iface $item Existing order to fetch the services from */ protected function setServices(\Aimeos\MShop\Order\Item\Base\Iface $order, \Aimeos\MShop\Order\Item\Iface $item) { $services = $order->getServices(); if (empty($services) && $this->getConfigValue('autofill.orderservice', true) == true) { $manager = \Aimeos\MShop\Factory::createManager($this->getContext(), 'order/base/service'); $search = $manager->createSearch(); $search->setConditions($search->compare('==', 'order.base.service.baseid', $item->getBaseId())); $services = $manager->searchItems($search); foreach ($services as $service) { $type = $service->getType(); if (($item = $this->getServiceItem($order, $type, $service->getCode())) !== null) { $order->setService($item, $type); } } } }
/** * Tries to get an authorization or captures the money immediately for the given order if capturing the money * separately isn't supported or not configured by the shop owner. * * @param \Aimeos\MShop\Order\Item\Iface $order Order invoice object * @param array $params Request parameter if available * @return \Aimeos\MShop\Common\Item\Helper\Form\Standard Form object with URL, action and parameters to redirect to * (e.g. to an external server of the payment provider or to a local success page) */ protected function processOrder(\Aimeos\MShop\Order\Item\Iface $order, array $params = array()) { $urls = $this->getPaymentUrls(); $parts = \Aimeos\MShop\Order\Manager\Base\Base::PARTS_SERVICE | \Aimeos\MShop\Order\Manager\Base\Base::PARTS_ADDRESS; $base = $this->getOrderBase($order->getBaseId(), $parts); $desc = $this->getContext()->getI18n()->dt('mshop', 'Order %1$s'); $card = $this->getCardDetails($base, $params); $orderid = $order->getId(); $data = array('token' => '', 'card' => $card, 'transactionId' => $orderid, 'description' => sprintf($desc, $orderid), 'amount' => $this->getAmount($base->getPrice()), 'currency' => $base->getLocale()->getCurrencyId(), 'language' => $base->getAddress(\Aimeos\MShop\Order\Item\Base\Address\Base::TYPE_PAYMENT)->getLanguageId(), 'clientIp' => $this->getValue('client.ipaddress')) + $urls; try { $provider = $this->getProvider(); if ($this->getValue('authorize', false) && $provider->supportsAuthorize()) { $response = $provider->authorize($data)->send(); $status = \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED; } else { $response = $provider->purchase($data)->send(); $status = \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED; } if ($response->isSuccessful()) { $this->saveTransationRef($base, $response->getTransactionReference()); $order->setPaymentStatus($status); $this->saveOrder($order); } elseif ($response->isRedirect()) { if (($ref = $response->getTransactionReference()) != null) { $this->saveTransationRef($base, $ref); } return $this->getRedirectForm($response); } else { $order->setPaymentStatus(\Aimeos\MShop\Order\Item\Base::PAY_REFUSED); $this->saveOrder($order); throw new \Aimeos\MShop\Service\Exception($response->getMessage()); } } catch (\Exception $e) { throw new \Aimeos\MShop\Service\Exception($e->getMessage()); } return new \Aimeos\MShop\Common\Item\Helper\Form\Standard($urls['returnUrl'], 'POST', array()); }
/** * Cancels the authorization for the given order if supported. * * @param \Aimeos\MShop\Order\Item\Iface $order Order invoice object */ public function cancel(\Aimeos\MShop\Order\Item\Iface $order) { if (($tid = $this->getOrderServiceItem($order->getBaseId())->getAttribute('TRANSACTIONID', 'payment/paypal')) === null) { $msg = sprintf('PayPal Express: Payment transaction ID for order ID "%1$s" not available', $order->getId()); throw new \Aimeos\MShop\Service\Exception($msg); } $values = $this->getAuthParameter(); $values['METHOD'] = 'DoVoid'; $values['AUTHORIZATIONID'] = $tid; $urlQuery = http_build_query($values, '', '&'); $response = $this->getCommunication()->transmit($this->apiendpoint, 'POST', $urlQuery); $this->checkResponse($order->getId(), $response, __METHOD__); $order->setPaymentStatus(\Aimeos\MShop\Order\Item\Base::PAY_CANCELED); $this->saveOrder($order); }
/** * Increases or decreses the stock levels of the products referenced in the order by the given value. * * @param \Aimeos\MShop\Order\Item\Iface $orderItem Order item object * @param integer $how Positive or negative integer number for increasing or decreasing the stock levels */ protected function updateStock(\Aimeos\MShop\Order\Item\Iface $orderItem, $how = +1) { $context = $this->getContext(); $productManager = \Aimeos\MShop\Factory::createManager($context, 'product'); $stockManager = \Aimeos\MShop\Factory::createManager($context, 'product/stock'); $manager = \Aimeos\MShop\Factory::createManager($context, 'order/base/product'); $search = $manager->createSearch(); $search->setConditions($search->compare('==', 'order.base.product.baseid', $orderItem->getBaseId())); $start = 0; $stockManager->begin(); try { do { $items = $manager->searchItems($search); foreach ($items as $item) { $stockManager->increase($item->getProductCode(), $item->getWarehouseCode(), $how * $item->getQuantity()); // recalculate stock level of product bundles $search = $productManager->createSearch(); $expr = array($search->compare('==', 'product.type.code', 'bundle'), $search->compare('==', 'product.lists.domain', 'product'), $search->compare('==', 'product.lists.refid', $item->getProductId()), $search->compare('==', 'product.lists.type.code', 'default')); $search->setConditions($search->combine('&&', $expr)); $search->setSlice(0, 0x7fffffff); $bundleItems = $productManager->searchItems($search, array('product')); $this->updateStockBundle($bundleItems, $item->getWarehouseCode()); } $count = count($items); $start += $count; $search->setSlice($start); } while ($count >= $search->getSliceSize()); $stockManager->commit(); } catch (\Exception $e) { $stockManager->rollback(); throw $e; } }
/** * Tries to get an authorization or captures the money immediately for the given order if capturing the money * separately isn't supported or not configured by the shop owner. * * @param \Aimeos\MShop\Order\Item\Iface $order Order invoice object * @param array $params Request parameter if available * @return \Aimeos\MShop\Common\Item\Helper\Form\Standard Form object with URL, action and parameters to redirect to * (e.g. to an external server of the payment provider or to a local success page) */ protected function processOrder(\Aimeos\MShop\Order\Item\Iface $order, array $params = array()) { $parts = \Aimeos\MShop\Order\Manager\Base\Base::PARTS_SERVICE | \Aimeos\MShop\Order\Manager\Base\Base::PARTS_ADDRESS; $base = $this->getOrderBase($order->getBaseId(), $parts); $data = $this->getData($base, $order->getId(), $params); $urls = $this->getPaymentUrls(); try { $provider = $this->getProvider(); if ($this->getValue('authorize', false) && $provider->supportsAuthorize()) { $response = $provider->authorize($data)->send(); $status = \Aimeos\MShop\Order\Item\Base::PAY_AUTHORIZED; } else { $response = $provider->purchase($data)->send(); $status = \Aimeos\MShop\Order\Item\Base::PAY_RECEIVED; } if ($response->isSuccessful()) { $this->saveTransationRef($base, $response->getTransactionReference()); $order->setPaymentStatus($status); $this->saveOrder($order); } elseif ($response->isRedirect()) { if (($ref = $response->getTransactionReference()) != null) { $this->saveTransationRef($base, $ref); } return $this->getRedirectForm($response); } else { $order->setPaymentStatus(\Aimeos\MShop\Order\Item\Base::PAY_REFUSED); $this->saveOrder($order); throw new \Aimeos\MShop\Service\Exception($response->getMessage()); } } catch (\Exception $e) { throw new \Aimeos\MShop\Service\Exception($e->getMessage()); } return new \Aimeos\MShop\Common\Item\Helper\Form\Standard($urls['returnUrl'], 'POST', array()); }
/** * Increases or decreses the stock levels of the products referenced in the order by the given value. * * @param \Aimeos\MShop\Order\Item\Iface $orderItem Order item object * @param integer $how Positive or negative integer number for increasing or decreasing the stock levels */ protected function updateStock(\Aimeos\MShop\Order\Item\Iface $orderItem, $how = +1) { $context = $this->getContext(); $stockManager = \Aimeos\MShop\Factory::createManager($context, 'product/stock'); $manager = \Aimeos\MShop\Factory::createManager($context, 'order/base/product'); $search = $manager->createSearch(); $search->setConditions($search->compare('==', 'order.base.product.baseid', $orderItem->getBaseId())); $start = 0; $stockManager->begin(); try { do { $items = $manager->searchItems($search); foreach ($items as $item) { $stockManager->increase($item->getProductCode(), $item->getWarehouseCode(), $how * $item->getQuantity()); switch ($item->getType()) { case 'default': $this->updateStockBundle($item->getProductId(), $item->getWarehouseCode()); break; case 'select': $this->updateStockSelection($item->getProductId(), $item->getWarehouseCode()); break; } } $count = count($items); $start += $count; $search->setSlice($start); } while ($count >= $search->getSliceSize()); $stockManager->commit(); } catch (\Exception $e) { $stockManager->rollback(); throw $e; } }