-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #59 from airwallex/bugfix
Bugfix
- Loading branch information
Showing
13 changed files
with
290 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
154 changes: 154 additions & 0 deletions
154
Controller/Adminhtml/Configuration/SetUpdateSettingsMessage.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
<?php | ||
|
||
namespace Airwallex\Payments\Controller\Adminhtml\Configuration; | ||
|
||
use Airwallex\Payments\Helper\Configuration; | ||
use Magento\Framework\DataObject\IdentityService; | ||
use Magento\Framework\Exception\LocalizedException; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\Math\Random; | ||
use Magento\Backend\App\Action; | ||
use Magento\Backend\App\Action\Context; | ||
use Magento\Framework\Controller\Result\Json; | ||
use Magento\Framework\Controller\Result\JsonFactory; | ||
use Magento\Framework\UrlInterface; | ||
use Magento\Store\Model\StoreManager; | ||
use Magento\Framework\App\CacheInterface; | ||
use Magento\Framework\App\RequestInterface; | ||
|
||
class SetUpdateSettingsMessage extends Action | ||
{ | ||
public const CACHE_NAME = 'airwallex_update_settings_token'; | ||
|
||
protected JsonFactory $resultJsonFactory; | ||
protected Context $context; | ||
protected StoreManager $storeManager; | ||
protected Random $random; | ||
protected CacheInterface $cache; | ||
protected RequestInterface $request; | ||
protected Configuration $configuration; | ||
protected IdentityService $identityService; | ||
|
||
public function __construct( | ||
Context $context, | ||
JsonFactory $resultJsonFactory, | ||
StoreManager $storeManager, | ||
Random $random, | ||
CacheInterface $cache, | ||
RequestInterface $request, | ||
Configuration $configuration, | ||
IdentityService $identityService | ||
) | ||
{ | ||
parent::__construct($context); | ||
$this->resultJsonFactory = $resultJsonFactory; | ||
$this->context = $context; | ||
$this->storeManager = $storeManager; | ||
$this->random = $random; | ||
$this->cache = $cache; | ||
$this->request = $request; | ||
$this->configuration = $configuration; | ||
$this->identityService = $identityService; | ||
} | ||
|
||
public function getOriginFromUrl($url): string | ||
{ | ||
$parsedUrl = parse_url($url); | ||
$origin = $parsedUrl['scheme'] . '://' . $parsedUrl['host']; | ||
if (isset($parsedUrl['port'])) { | ||
$origin .= ':' . $parsedUrl['port']; | ||
} | ||
return $origin; | ||
} | ||
|
||
/** | ||
* @return Json | ||
* @throws NoSuchEntityException|LocalizedException | ||
*/ | ||
public function execute(): Json | ||
{ | ||
$resultJson = $this->resultJsonFactory->create(); | ||
if (empty($this->request->getParam('code'))) { | ||
header('Location: ' . base64_decode($this->request->getParam('target_url'))); | ||
return $resultJson; | ||
} | ||
$environment = 'demo'; | ||
if ($this->request->getParam('env') !== 'demo') { | ||
$environment = 'www'; | ||
} | ||
$platform = 'magento'; | ||
$storeUrl = $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_WEB); | ||
$baseUrl = trim($storeUrl, '/'); | ||
$webhookNotificationUrl = $baseUrl . '/airwallex/webhooks'; | ||
if (!function_exists('gzdecode')) { | ||
return $this->error('Error: The gzdecode function is not available. Please make sure the zlib extension is enabled.', $resultJson); | ||
} | ||
|
||
$accessToken = gzdecode(base64_decode($this->request->getParam('code'))); | ||
$requestId = $this->identityService->generateId(); | ||
|
||
$url = "https://$environment.airwallex.com/payment_app/plugin/api/v1/connection/finalize"; | ||
$data = [ | ||
'platform' => $platform, | ||
'origin' => $this->getOriginFromUrl($baseUrl), | ||
'baseUrl' => $baseUrl, | ||
'webhookNotificationUrl' => $webhookNotificationUrl, | ||
'token' => $this->token($environment), | ||
'requestId' => $requestId | ||
]; | ||
|
||
if (!function_exists('curl_init')) { | ||
return $this->error('Error: Please make sure the curl extension is enabled.', $resultJson); | ||
} | ||
|
||
$options = [ | ||
'http' => [ | ||
'method' => 'POST', | ||
'header' => [ | ||
'Content-Type: application/json', | ||
'Authorization: Bearer ' . $accessToken, | ||
], | ||
'content' => json_encode($data), | ||
'ignore_errors' => true | ||
], | ||
]; | ||
|
||
$context = stream_context_create($options); | ||
$response = file_get_contents($url, false, $context); | ||
if ($response === false) { | ||
return $this->error('Error: Unable to fetch the URL. Please try again.', $resultJson); | ||
} | ||
$responseData = json_decode($response, true); | ||
|
||
if (!empty($responseData['message']) && $responseData['message'] == 'OK') { | ||
return $this->success('Your Airwallex plug-in is activated. | ||
You can also manage which account is connected to your Magento store.', $resultJson); | ||
} | ||
|
||
return $this->error($responseData['error'], $resultJson); | ||
} | ||
|
||
public function error($message, $resultJson): Json | ||
{ | ||
$this->context->getMessageManager()->addErrorMessage($message); | ||
header('Location: ' . base64_decode($this->request->getParam('target_url'))); | ||
return $resultJson; | ||
} | ||
|
||
public function success($message, $resultJson): Json | ||
{ | ||
$this->context->getMessageManager()->addSuccessMessage($message); | ||
header('Location: ' . base64_decode($this->request->getParam('target_url'))); | ||
return $resultJson; | ||
} | ||
|
||
/** | ||
* @throws LocalizedException | ||
*/ | ||
public function token($environment): string | ||
{ | ||
$token = $environment . '-' . $this->random->getRandomString(32); | ||
$this->cache->save($token, self::CACHE_NAME, [], 60 * 60 * 24); | ||
return $token; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
namespace Airwallex\Payments\Model\Config\Adminhtml; | ||
|
||
use Airwallex\Payments\Helper\Configuration; | ||
use Magento\Config\Block\System\Config\Form\Field; | ||
use Magento\Framework\App\ObjectManager; | ||
use Magento\Framework\Data\Form\Element\AbstractElement; | ||
use Magento\Framework\Exception\LocalizedException; | ||
|
||
class UpdateSettings extends Field | ||
{ | ||
protected $_template = 'Airwallex_Payments::config/update_settings.phtml'; | ||
|
||
protected function _getElementHtml(AbstractElement $element): string | ||
{ | ||
return $this->_toHtml(); | ||
} | ||
|
||
public function render(AbstractElement $element): string | ||
{ | ||
$element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue(); | ||
return parent::render($element); | ||
} | ||
|
||
public function getAccount() | ||
{ | ||
return ObjectManager::getInstance()->get(Configuration::class)->getAccount(); | ||
} | ||
|
||
/** | ||
* @throws LocalizedException | ||
*/ | ||
public function getButtonHtml() | ||
{ | ||
$data = [ | ||
'id' => 'airwallex_update_settings', | ||
'label' => __('Connect account'), | ||
]; | ||
|
||
return $this->getLayout()->createBlock('Magento\Backend\Block\Widget\Button')->setData($data)->toHtml(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php /** @var \Airwallex\Payments\Model\Config\Adminhtml\UpdateSettings $block */ ?> | ||
<script> | ||
require([ | ||
'jquery' | ||
], | ||
function (jQuery) { | ||
let accountStr = '<?= $this->getAccount() ?>'; | ||
let account = accountStr ? JSON.parse(accountStr) : {}; | ||
let typeSelector = '[name="groups[airwallex_payments][groups][basic][fields][mode][value]"]'; | ||
let env = document.querySelector(typeSelector).value; | ||
|
||
let setting = function () { | ||
let env = document.querySelector(typeSelector).value; | ||
let connectedSelector = "#awx-connected"; | ||
if (!account[env + "_account_id"]) { | ||
jQuery(connectedSelector).hide(); | ||
jQuery("#airwallex_update_settings").html('Connect account'); | ||
} else { | ||
jQuery(connectedSelector).show(); | ||
jQuery(connectedSelector).html(account[env + "_account_name"]); | ||
jQuery("#airwallex_update_settings").html('Manage'); | ||
} | ||
}; | ||
|
||
jQuery(document).ready(setting); | ||
jQuery(typeSelector).on('change', setting); | ||
|
||
function uuid() { | ||
let S4 = function () { | ||
return ((1 + Math.random()) * 0X10000 | 0).toString(16).substring(1); | ||
}; | ||
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); | ||
} | ||
|
||
jQuery('#airwallex_update_settings').click(function () { | ||
let env = document.querySelector(typeSelector).value; | ||
let redirectUrl = '<?= $block->escapeJs($block->getUrl('airwallex/configuration/setUpdateSettingsMessage')) ?>'; | ||
redirectUrl += "?target_url=" + btoa(location.href) + '&env=' + env; | ||
let awxUrl = 'https://demo.airwallex.com/'; | ||
if (env === 'prod') { | ||
awxUrl = awxUrl.replace('demo.airwallex', 'www.airwallex'); | ||
} | ||
const connectedAccountId = account[`${env}_account_id`] || ''; | ||
const params = new URLSearchParams({ | ||
platform: 'magento', | ||
origin: location.href, | ||
returnUrl: redirectUrl, | ||
requestId: uuid(), | ||
connectedAccountId: connectedAccountId, | ||
}); | ||
|
||
location.href = `${awxUrl.trim()}payment_app/plugin/api/v1/connection/start?${params.toString()}`; | ||
}); | ||
}); | ||
</script> | ||
|
||
|
||
<div style="display: flex"> | ||
<div id="awx-connected" class="awx-connect-tip"> | ||
</div> | ||
<?php echo $block->getButtonHtml() ?> | ||
</div> | ||
|
||
<style> | ||
.awx-connect-tip { | ||
margin: 10px 10px 10px 0; | ||
} | ||
|
||
.awx-connect-tip .title { | ||
font-weight: bold; | ||
margin-bottom: 5px; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters