*/ class Request extends DataObject { use Formatter; /** * Request's order model * * @var \Magento\Sales\Model\Order */ protected $order; /** * Request's Hosted Pro payment method model * * @var \Magento\Paypal\Model\Hostedpro */ protected $paymentMethod; /** * Name format for button variables * * @var string */ protected $buttonVarFormat = 'L_BUTTONVAR%d'; /** * Request Parameters which dont have to wrap as button vars * * @var string[] */ protected $notButtonVars = ['METHOD', 'BUTTONCODE', 'BUTTONTYPE']; /** * Customer address * * @var \Magento\Customer\Helper\Address */ protected $customerAddress = null; /** * Tax data * * @var \Magento\Tax\Helper\Data */ protected $taxData; /** * Locale Resolver * * @var \Magento\Framework\Locale\Resolver */ protected $localeResolver; /** * @param \Magento\Framework\Locale\Resolver $localeResolver * @param \Magento\Customer\Helper\Address $customerAddress * @param \Magento\Tax\Helper\Data $taxData * @param array $data */ public function __construct( Resolver $localeResolver, Address $customerAddress, Data $taxData, array $data = [] ) { $this->customerAddress = $customerAddress; $this->localeResolver = $localeResolver; $this->taxData = $taxData; parent::__construct($data); } /** * Build and return request array from object data * * @return array */ public function getRequestData() { $requestData = []; if (!empty($this->_data)) { // insert params to request as additional button variables, // except special params from _notButtonVars list $i = 0; foreach ($this->_data as $key => $value) { if (in_array($key, $this->notButtonVars)) { $requestData[$key] = $value; } else { $varKey = sprintf($this->buttonVarFormat, $i); $requestData[$varKey] = $key . '=' . $value; $i++; } } } return $requestData; } /** * Append payment data to request * * @param \Magento\Paypal\Model\Hostedpro $paymentMethod * @return $this */ public function setPaymentMethod($paymentMethod) { $this->paymentMethod = $paymentMethod; $requestData = $this->getPaymentData($paymentMethod); $this->addData($requestData); return $this; } /** * Append order data to request * * @param \Magento\Sales\Model\Order $order * @return $this */ public function setOrder(Order $order) { $this->order = $order; $requestData = $this->getOrderData($order); $this->addData($requestData); return $this; } /** * Add amount data to request * * @access public * @param \Magento\Sales\Model\Order $order * @return $this */ public function setAmount(Order $order) { $this->addData($this->getAmountData($order)); return $this; } /** * Calculate amount for order * @param \Magento\Sales\Model\Order $order * @return array * @throws \Exception */ protected function getAmountData(Order $order) { // if tax is included - need add to request only total amount if ($this->taxData->getConfig()->priceIncludesTax()) { return $this->getTaxableAmount($order); } else { return $this->getNonTaxableAmount($order); } } /** * Get payment amount data with excluded tax * @param \Magento\Sales\Model\Order $order * @return array */ private function getNonTaxableAmount(Order $order) { // PayPal denied transaction with 0 amount $subtotal = $order->getBaseSubtotal() ? : $order->getPayment()->getBaseAmountAuthorized(); return [ 'subtotal' => $this->formatPrice($subtotal), 'total' => $this->formatPrice($order->getPayment()->getBaseAmountAuthorized()), 'tax' => $this->formatPrice($order->getBaseTaxAmount()), 'shipping' => $this->formatPrice($order->getBaseShippingAmount()), 'discount' => $this->formatPrice(abs($order->getBaseDiscountAmount())) ]; } /** * Get order amount data with included tax * @param \Magento\Sales\Model\Order $order * @return array */ private function getTaxableAmount(Order $order) { $amount = $this->formatPrice($order->getPayment()->getBaseAmountAuthorized()); return [ 'amount' => $amount, 'subtotal' => $amount // subtotal always is required ]; } /** * Get payment request data as array * * @param \Magento\Paypal\Model\Hostedpro $paymentMethod * @return array */ protected function getPaymentData(Hostedpro $paymentMethod) { $request = [ 'paymentaction' => strtolower($paymentMethod->getConfigData('payment_action')), 'notify_url' => $paymentMethod->getNotifyUrl(), 'cancel_return' => $paymentMethod->getCancelUrl(), 'return' => $paymentMethod->getReturnUrl(), 'lc' => \Locale::getRegion($this->localeResolver->getLocale()), 'template' => 'mobile-iframe', 'showBillingAddress' => 'false', 'showShippingAddress' => 'true', 'showBillingEmail' => 'false', 'showBillingPhone' => 'false', 'showCustomerName' => 'false', 'showCardInfo' => 'true', 'showHostedThankyouPage' => 'false', ]; return $request; } /** * Get order request data as array * * @param \Magento\Sales\Model\Order $order * @return array */ protected function getOrderData(Order $order) { $request = [ 'invoice' => $order->getIncrementId(), 'address_override' => 'true', 'currency_code' => $order->getBaseCurrencyCode(), 'buyer_email' => $order->getCustomerEmail(), ]; // append to request billing address data if ($billingAddress = $order->getBillingAddress()) { $request = array_merge($request, $this->getAddress($billingAddress, 'billing')); } // append to request shipping address data if ($shippingAddress = $order->getShippingAddress()) { $request = array_merge($request, $this->getAddress($shippingAddress)); } return $request; } /** * Export address data to request * * @param DataObject $address * @param string $type * @return array */ protected function getAddress(DataObject $address, $type = '') { $type = !empty($type) ? $type . '_' : ''; $request = [ $type . 'first_name' => $address->getFirstname(), $type . 'last_name' => $address->getLastname(), $type . 'city' => $address->getCity(), $type . 'state' => $this->getRegion($address), $type . 'zip' => $address->getPostcode(), $type . 'country' => $address->getCountryId(), ]; $streets = $this->getAddressStreets($address); $request[$type . 'address1'] = $streets[0]; $request[$type . 'address2'] = $streets[1]; return $request; } /** * Export region code from address data * * @param DataObject $address * @return string */ protected function getRegion(DataObject $address) { // get region code, otherwise - region, otherwise - city return $address->getRegionCode() ?: ($address->getRegion() ?: $address->getCity()); } /** * Export streets from address data * * @param DataObject $address * @return array */ protected function getAddressStreets(DataObject $address) { $street1 = ''; $street2 = ''; $data = $this->customerAddress->convertStreetLines($address->getStreet(), 2); if (!empty($data[0])) { $street1 = $data[0]; } if (!empty($data[1])) { $street2 = $data[1]; } return [$street1, $street2]; } }