<?php declare(strict_types=1); namespace Lexim\Override\Controller\Currency; use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\App\ActionInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\Http\Context as HttpContext; use Magento\Framework\Controller\Result\Json; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\HTTP\Client\Curl; use Magento\Framework\HTTP\PhpEnvironment\Request as HttpRequest; use Magento\Framework\Controller\Result\JsonFactory; use Magento\Store\Model\StoreIsInactiveException; use Magento\Store\Model\StoreManagerInterface; use Magento\Store\Api\StoreRepositoryInterface; use Magento\Store\Api\StoreCookieManagerInterface; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; /** * Class Change * * @package Lexim\Override\Controller\Currency */ class Change implements ActionInterface, HttpPostActionInterface { /** @var RequestInterface */ private $request; /** @var Curl */ private $_curl; /** @var HttpRequest */ private $httpRequest; /** @var JsonFactory */ private $resultJsonFactory; /** @var StoreManagerInterface */ private $storeManager; /** @var UrlFinderInterface */ private $urlFinder; /** @var StoreRepositoryInterface */ private $storeRepository; /** @var StoreCookieManagerInterface */ private $storeCookieManager; /** @var HttpContext */ private $httpContext; /** * @param RequestInterface $request * @param HttpContext $httpContext * @param JsonFactory $resultJsonFactory * @param Curl $curl * @param StoreManagerInterface $storeManager * @param StoreRepositoryInterface $storeRepository * @param StoreCookieManagerInterface $storeCookieManager * @param HttpRequest $httpRequest * @param UrlFinderInterface $urlFinder */ public function __construct( RequestInterface $request, HttpContext $httpContext, JsonFactory $resultJsonFactory, Curl $curl, StoreManagerInterface $storeManager, StoreRepositoryInterface $storeRepository, StoreCookieManagerInterface $storeCookieManager, HttpRequest $httpRequest, UrlFinderInterface $urlFinder, ) { $this->request = $request; $this->resultJsonFactory = $resultJsonFactory; $this->_curl = $curl; $this->storeManager = $storeManager; $this->storeRepository = $storeRepository; $this->storeCookieManager = $storeCookieManager; $this->httpContext = $httpContext; $this->httpRequest = $httpRequest; $this->urlFinder = $urlFinder; } /** * Switch Store by country IP * * @return Json * @throws NoSuchEntityException * @throws StoreIsInactiveException * @throws \Zend_Log_Exception */ public function execute() { // TODO: Implement execute() method. $url = $this->request->getParam('url'); $countryCode = $this->request->getParam('countryCode'); // Response Data $curStoreCode = $this->storeManager->getStore()->getCode(); // english, french, us $data = [ 'oldUrl' => $url, 'ip' => false, 'switch' => false, 'curStoreCode' => $curStoreCode, 'curStore' => $curStoreCode === 'us' ? 'us' : 'ca', 'targetStoreCode' => 'us', 'apiWorked' => false, 'countryCode' => '', 'targetStore' => 'us' ]; // Check country by IP if the country is null if (!$countryCode || $countryCode === '') { $ip = $this->httpRequest->getClientIp(true); $ip = explode(',', strval($ip)); if (is_array($ip) && count($ip) > 0) { $ip = reset($ip); } if ($ip) { //$ip = '113.160.226.108'; // VN 113.160.226.108 //$ip = '173.238.88.28'; // CA 204.41.127.133 //$ip = '52.12.129.239'; // US 52.12.129.239 $data['ip'] = $ip; $ipResponseArray = $this->_getCountryFromIp($ip); if ($ipResponseArray && is_array($ipResponseArray)) { $data = array_merge($data, $ipResponseArray); } } } // Switch store if (in_array($data['countryCode'], ['CA', 'VN'])) { // in_array($countryCode, ['CA', 'VN'] $data['targetStore'] = "ca"; $data['targetStoreCode'] = 'english'; // CA_en } if ($data['curStore'] !== $data['targetStore'] && $data['targetStore'] === "ca") { $data['switch'] = true; if ($curStoreCode === 'french') { // Rewrite path url from French to US $pathRedirect = $this->getRequest()->getParam('path'); $pageType = $this->getRequest()->getParam('pageType'); $data['pageType'] = $pageType; $stores = $this->storeManager->getStores(true, true); if ($pageType === 'staticPage') { // cms static page $rewrite = $this->urlFinder->findOneByData( [ UrlRewrite::TARGET_PATH => $pathRedirect, UrlRewrite::STORE_ID => $stores['french']->getId(), // 2 french, 1 eng, 4 us UrlRewrite::REDIRECT_TYPE => 302 ] ); if ($rewrite) { $data['pathRedirect'] = $rewrite->getRequestPath(); } } else if ($pageType === 'another') { // another pages exclude home page $rewrite = $this->urlFinder->findOneByData( [ UrlRewrite::REQUEST_PATH => $pathRedirect, UrlRewrite::STORE_ID => $stores['french']->getId(), ] ); if ($rewrite) { $targetPath = $rewrite->getTargetPath(); if ($targetPath) { $rewriteUS = $this->urlFinder->findOneByData( [ UrlRewrite::TARGET_PATH => $targetPath, UrlRewrite::STORE_ID => $stores['us']->getId(), ] ); if ($rewriteUS) { $data['pathRedirect'] = $rewriteUS->getRequestPath(); } } } } } // Switch Store to English CA $data['targetStoreCode'] = 'english'; $store = $this->storeRepository->getActiveStoreByCode('english'); $this->httpContext->setValue('store', 'english', 'english'); $this->storeCookieManager->setStoreCookie($store); } // response $result = $this->resultJsonFactory->create(); return $result->setData($data); } /** * @param $ip * * @return array|false */ private function _getCountryFromIp($ip) { if (!$ip) { return false; } $data = [ 'apiWorked' => false, 'countryCode' => '', 'apiUrl' => '' ]; $ipFile = BP . '/var/ip/' . $ip; $_getCountryFromFile = false; // Use saved files if (file_exists($ipFile)) { $response = file_get_contents($ipFile); $response = json_decode($response, true); if (isset($response['countryCode'])) { $data['countryCode'] = $response['countryCode']; $data['apiUrl'] = 'fromIpFolder'; $_getCountryFromFile = true; } } /** * Use API and prepare response data to the below format JSON before save to file * Format response: {"status":"success","countryCode":"CA","query":"173.238.88.28"} */ if (!$_getCountryFromFile) { /** * API (open source): https://api.country.is/ * Country is an geolocation API that finds a user's country and nothing else from their IP. * It works both with IPv4 and IPv6. * The public instance we run at api.country.is is free to use. * It does not require an API key or impose usage quotas. * https://api.country.is/113.160.226.108 */ $apiUrl = 'https://api.country.is/' . $ip; $this->_curl->addHeader('accept', 'application/json'); // fix bug SSL certificate has expired $this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false); $this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false); $this->_curl->get($apiUrl); $body = $this->_curl->getBody(); $response = json_decode($body, true); if (isset($response['country'])) { $data['apiWorked'] = true; $data['countryCode'] = $response['country']; $data['apiUrl'] = 'api.country.is'; $json = '{"countryCode":"' . $response['country'] . '","ip":"' . $ip . '"}'; $this->_saveIpResponse($ip, $json); } else { /** * API: ip-api.com * Free for non-commercial use, no API key required * Limited to 45 HTTP requests per minute from an IP address * The average response time of the API: under 50 milliseconds in most parts of the world. */ $apiUrl = 'http://ip-api.com/json/'; $apiUrl .= $ip; $apiUrl .= '?fields=status,message,countryCode,query'; $this->_curl->addHeader('accept', 'application/json'); $this->_curl->get($apiUrl); $body = $this->_curl->getBody(); $response = json_decode($body, true); if (isset($response['countryCode'])) { $data['apiWorked'] = true; $data['countryCode'] = $response['countryCode']; $data['apiUrl'] = 'ip-api.com'; $json = '{"countryCode":"' . $response['countryCode'] . '","ip":"' . $ip . '"}'; $this->_saveIpResponse($ip, $json); } else { /** * API: https://ipapi.co/173.238.88.28/country_code => 'CA' * Free: 30k request per month, up to 1000 request per day */ $apiUrl = 'https://ipapi.co/' . $ip . '/country_code'; $this->_curl->get($apiUrl); $countryCode = trim($this->_curl->getBody()); if ($countryCode && $countryCode != 'Undefined') { $data['apiWorked'] = true; $data['countryCode'] = $countryCode; $data['apiUrl'] = 'ipapi.co/IP/country_code'; $json = '{"countryCode":"' . $countryCode . '","ip":"' . $ip . '"}'; $this->_saveIpResponse($ip, $json); } } } } return $data; } /** * @param string $ip * @param string $response * * @return false|int */ private function _saveIpResponse(string $ip, string $response) { if (!$ip || !$response) { return false; } $folderPath = BP . '/var/ip/'; // Check if the folder exists, create it if not if (!file_exists($folderPath)) { mkdir($folderPath, 0777, true); } $filePath = $folderPath . $ip; return file_put_contents($filePath, $response); } }
Search
Jan 3, 2024
Magento 2: Create controller to get country by IP client via API free, store in local files for using in the next time
Dec 7, 2023
Get transaction (profile id, payment id) from order in magento 2
<?php use Magento\Sales\Api\Data\TransactionInterface; use Magento\Sales\Api\TransactionRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\HTTP\Client\Curl; class ... { /** @var TransactionRepositoryInterface */ private $_transactionRepositoryInterface; /** @var SearchCriteriaBuilder */ private $_searchCriteriaBuilder; /** @var Curl */ private $_curl; /** * ... * @param Curl $_curl * @param TransactionRepositoryInterface $_transactionRepositoryInterface * @param SearchCriteriaBuilder $_searchCriteriaBuilder */ public function __construct( ... Curl $_curl, TransactionRepositoryInterface $_transactionRepositoryInterface, SearchCriteriaBuilder $_searchCriteriaBuilder ) { parent::__construct(...); $this->_curl = $_curl; $this->_transactionRepositoryInterface = $_transactionRepositoryInterface; $this->_searchCriteriaBuilder = $_searchCriteriaBuilder; } public function excute() { $orderId = 123; $trans = $this->_getTransactionFromOrder($orderId); $tran = false; if (is_array($trans) && count($trans) > 0) { $tran = reset($trans); } if ($tran) { /** @var TransactionInterface $trans */ $transId = $tran->getTxnId(); echo "<br>Trans ID: " . $transId . "<br>"; $addInfo = $tran->getAdditionalInformation(); if (isset($addInfo["raw_details_info"]["profile_id"])) { echo "<br>profile_id: " . $addInfo["raw_details_info"]["profile_id"]; } if (isset($addInfo["raw_details_info"]["payment_id"])) { echo "<br>payment_id: " . $addInfo["raw_details_info"]["payment_id"]; } } // Get Data by Trans ID from Authorize net API $transId = 4444; $data = $this->_getTransDetail($transId); } /** * @param $orderId * * @return TransactionInterface[] */ private function _getTransactionFromOrder($orderId) { $this->_searchCriteriaBuilder->addFilter('order_id', $orderId); $list = $this->_transactionRepositoryInterface->getList( $this->_searchCriteriaBuilder->create() ); return $list->getItems(); } /** * Get Transaction Detail from authorize net API * @param $transId * * @return false|string */ private function _getTransDetail($transId) { if (!$transId) { return false; } try { // Set the external URL $apiUrl = 'https://apitest.authorize.net/xml/v1/request.api'; $apiUrlProduction = 'https://api.authorize.net/xml/v1/request.api'; // Set the POST data as JSON $postData = [ 'getTransactionDetailsRequest' => [ 'merchantAuthentication' => [ 'name' => 'API_USER_ID', 'transactionKey' => 'TRANS_KEY', ], 'transId' => $transId, ], ]; $postDataJson = json_encode($postData); // Make the POST request $this->_curl->post($apiUrl, $postDataJson); $response = $this->_curl->getBody(); return $response; } catch (\Exception $e) { return false; } } }
Subscribe to:
Posts (Atom)