<?php /** * ###### * ###### * ############ ####( ###### #####. ###### ############ ############ * ############# #####( ###### #####. ###### ############# ############# * ###### #####( ###### #####. ###### ##### ###### ##### ###### * ###### ###### #####( ###### #####. ###### ##### ##### ##### ###### * ###### ###### #####( ###### #####. ###### ##### ##### ###### * ############# ############# ############# ############# ##### ###### * ############ ############ ############# ############ ##### ###### * ###### * ############# * ############ * * Adyen Payment module (https://www.adyen.com/) * * Copyright (c) 2015 Adyen BV (https://www.adyen.com/) * See LICENSE.txt for license details. * * Author: Adyen <magento@adyen.com> */ namespace Adyen\Payment\Model\Method; use Magento\Framework\DataObject; use Magento\Payment\Model\Method\ConfigInterface; use Magento\Payment\Model\Method\Online\GatewayInterface; /** * @SuppressWarnings(PHPMD.ExcessivePublicCount) * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Hpp extends \Magento\Payment\Model\Method\AbstractMethod implements GatewayInterface { const METHOD_CODE = 'adyen_hpp'; /** * @var string */ protected $_code = self::METHOD_CODE; /** * @var GUEST_ID , used when order is placed by guests */ const GUEST_ID = 'customer_'; // protected $_formBlockType = 'Adyen\Payment\Block\Form\Hpp'; protected $_infoBlockType = 'Adyen\Payment\Block\Info\Hpp'; /** * Payment Method feature * * @var bool */ protected $_isGateway = true; protected $_canAuthorize = true; protected $_isInitializeNeeded = true; protected $_canRefund = true; protected $_canRefundInvoicePartial = true; /** * @var \Adyen\Payment\Model\Api\PaymentRequest */ protected $_paymentRequest; /** * @var \Adyen\Payment\Helper\Data */ protected $_adyenHelper; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; /** * @var \Magento\Framework\UrlInterface */ protected $_urlBuilder; /** * @var ResolverInterface */ protected $resolver; /** * @var \Adyen\Payment\Logger\AdyenLogger */ protected $_adyenLogger; /** * @param \Adyen\Payment\Model\Api\PaymentRequest $paymentRequest * @param \Magento\Framework\UrlInterface $urlBuilder * @param \Adyen\Payment\Helper\Data $adyenHelper * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Locale\ResolverInterface $resolver * @param \Adyen\Payment\Logger\AdyenLogger $adyenLogger * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory * @param \Magento\Payment\Helper\Data $paymentData * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Payment\Model\Method\Logger $logger * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Adyen\Payment\Model\Api\PaymentRequest $paymentRequest, \Magento\Framework\UrlInterface $urlBuilder, \Adyen\Payment\Helper\Data $adyenHelper, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Locale\ResolverInterface $resolver, \Adyen\Payment\Logger\AdyenLogger $adyenLogger, \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory, \Magento\Payment\Helper\Data $paymentData, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Payment\Model\Method\Logger $logger, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [] ) { parent::__construct( $context, $registry, $extensionFactory, $customAttributeFactory, $paymentData, $scopeConfig, $logger, $resource, $resourceCollection, $data ); $this->_paymentRequest = $paymentRequest; $this->_urlBuilder = $urlBuilder; $this->_adyenHelper = $adyenHelper; $this->storeManager = $storeManager; $this->resolver = $resolver; $this->_adyenLogger = $adyenLogger; } protected $_paymentMethodType = 'hpp'; public function getPaymentMethodType() { return $this->_paymentMethodType; } public function initialize($paymentAction, $stateObject) { /* * do not send order confirmation mail after order creation wait for * Adyen AUTHORIISATION notification */ $payment = $this->getInfoInstance(); $order = $payment->getOrder(); $order->setCanSendNewEmailFlag(false); $state = \Magento\Sales\Model\Order::STATE_NEW; $stateObject->setState($state); $stateObject->setStatus($this->_adyenHelper->getAdyenAbstractConfigData('order_status')); } /** * Assign data to info model instance * * @param \Magento\Framework\DataObject|mixed $data * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ public function assignData(\Magento\Framework\DataObject $data) { parent::assignData($data); $infoInstance = $this->getInfoInstance(); if(isset($data['brand_code'])) { $infoInstance->setAdditionalInformation('brand_code', $data['brand_code']); } if(isset($data['issuer_id'])) { $infoInstance->setAdditionalInformation('issuer_id', $data['issuer_id']); } $this->_adyenLogger->info(print_r($data,1)); return $this; } /** * Checkout redirect URL getter for onepage checkout (hardcode) * * @see \Magento\Checkout\Controller\Onepage::savePaymentAction() * @see \Magento\Quote\Model\Quote\Payment::getCheckoutRedirectUrl() * @return string */ public function getCheckoutRedirectUrl() { return $this->_urlBuilder->getUrl('adyen/process/redirect'); } /** * Post request to gateway and return response * * @param Object $request * @param ConfigInterface $config * * @return Object * * @throws \Exception */ public function postRequest(DataObject $request, ConfigInterface $config) { // Implement postRequest() method. } /** * @desc Get url of Adyen payment * @return string */ public function getFormUrl() { $paymentRoutine = $this->getConfigData('payment_routine'); switch ($this->_adyenHelper->isDemoMode()) { case true: if ($paymentRoutine == 'single' && $this->getPaymentMethodSelectionOnAdyen()) { $url = 'https://test.adyen.com/hpp/pay.shtml'; } else { $url = ($this->getPaymentMethodSelectionOnAdyen()) ? 'https://test.adyen.com/hpp/select.shtml' : "https://test.adyen.com/hpp/details.shtml"; } break; default: if ($paymentRoutine == 'single' && $this->getPaymentMethodSelectionOnAdyen()) { $url = 'https://live.adyen.com/hpp/pay.shtml'; } else { $url = ($this->getPaymentMethodSelectionOnAdyen()) ? 'https://live.adyen.com/hpp/select.shtml' : "https://live.adyen.com/hpp/details.shtml"; } break; } return $url; } public function getFormFields() { $paymentInfo = $this->getInfoInstance(); $order = $paymentInfo->getOrder(); $realOrderId = $order->getRealOrderId(); $orderCurrencyCode = $order->getOrderCurrencyCode(); $skinCode = trim($this->getConfigData('skin_code')); $amount = $this->_adyenHelper->formatAmount($order->getGrandTotal(), $orderCurrencyCode); $merchantAccount = trim($this->_adyenHelper->getAdyenAbstractConfigData('merchant_account')); $shopperEmail = $order->getCustomerEmail(); $customerId = $order->getCustomerId(); $shopperIP = $order->getRemoteIp(); $browserInfo = $_SERVER['HTTP_USER_AGENT']; $deliveryDays = $this->getConfigData('delivery_days'); $shopperLocale = trim($this->getConfigData('shopper_locale')); $shopperLocale = (!empty($shopperLocale)) ? $shopperLocale : $this->resolver->getLocale(); $countryCode = trim($this->getConfigData('country_code')); $countryCode = (!empty($countryCode)) ? $countryCode : false; // if directory lookup is enabled use the billingadress as countrycode if ($countryCode == false) { if ($order->getBillingAddress() && $order->getBillingAddress()->getCountryId() != "") { $countryCode = $order->getBillingAddress()->getCountryId(); } } $formFields = array(); $formFields['merchantAccount'] = $merchantAccount; $formFields['merchantReference'] = $realOrderId; $formFields['paymentAmount'] = (int)$amount; $formFields['currencyCode'] = $orderCurrencyCode; $formFields['shipBeforeDate'] = date( "Y-m-d", mktime(date("H"), date("i"), date("s"), date("m"), date("j") + $deliveryDays, date("Y")) ); $formFields['skinCode'] = $skinCode; $formFields['shopperLocale'] = $shopperLocale; $formFields['countryCode'] = $countryCode; $formFields['shopperIP'] = $shopperIP; $formFields['browserInfo'] = $browserInfo; $formFields['sessionValidity'] = date( DATE_ATOM, mktime(date("H") + 1, date("i"), date("s"), date("m"), date("j"), date("Y")) ); $formFields['shopperEmail'] = $shopperEmail; // recurring $recurringType = trim($this->_adyenHelper->getAdyenAbstractConfigData('recurring_type')); $formFields['recurringContract'] = $recurringType; $formFields['shopperReference'] = (!empty($customerId)) ? $customerId : self::GUEST_ID . $realOrderId; //blocked methods $formFields['blockedMethods'] = ""; $baseUrl = $this->storeManager->getStore($this->getStore()) ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); $formFields['resURL'] = $baseUrl . 'adyen/process/result'; $hmacKey = $this->_adyenHelper->getHmac(); $brandCode = $order->getPayment()->getAdditionalInformation("brand_code"); if($brandCode) { $formFields['brandCode'] = $brandCode; } $issuerId = $order->getPayment()->getAdditionalInformation("issuer_id"); if($issuerId) { $formFields['issuerId'] = $issuerId; } // Sort the array by key using SORT_STRING order ksort($formFields, SORT_STRING); // Generate the signing data string $signData = implode(":",array_map(array($this, 'escapeString'),array_merge(array_keys($formFields), array_values($formFields)))); $merchantSig = base64_encode(hash_hmac('sha256',$signData,pack("H*" , $hmacKey),true)); $formFields['merchantSig'] = $merchantSig; $this->_adyenLogger->info(print_r($formFields, true)); return $formFields; } /* * @desc The character escape function is called from the array_map function in _signRequestParams * $param $val * return string */ protected function escapeString($val) { return str_replace(':','\\:',str_replace('\\','\\\\',$val)); } public function getPaymentMethodSelectionOnAdyen() { return $this->getConfigData('payment_selection_on_adyen'); } /** * Capture on Adyen * * @param \Magento\Payment\Model\InfoInterface $payment * @param float $amount */ public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount) { parent::capture($payment, $amount); $this->_paymentRequest->capture($payment, $amount); return $this; } /** * Refund specified amount for payment * * @param \Magento\Framework\DataObject|InfoInterface $payment * @param float $amount * @return $this * @throws \Magento\Framework\Exception\LocalizedException * @api * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount) { parent::refund($payment, $amount); // get pspReference $pspReference = $payment->getAdyenPspReference(); $order = $payment->getOrder(); // if amount is a full refund send a refund/cancelled request so if it is not captured yet it will cancel the order $grandTotal = $order->getGrandTotal(); if($grandTotal == $amount) { $this->_paymentRequest->cancelOrRefund($payment); } else { $this->_paymentRequest->refund($payment, $amount); } return $this; } }