Commit 30219bf9 by lmf

增加信用卡支付插件

parent 2e6888fd
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
"ext-xsl": "*", "ext-xsl": "*",
"ext-zip": "*", "ext-zip": "*",
"lib-libxml": "*", "lib-libxml": "*",
"airwallex/payments-plugin-magento": "^1.2",
"colinmollenhour/cache-backend-file": "~1.4.1", "colinmollenhour/cache-backend-file": "~1.4.1",
"colinmollenhour/cache-backend-redis": "1.11.0", "colinmollenhour/cache-backend-redis": "1.11.0",
"colinmollenhour/credis": "1.11.1", "colinmollenhour/credis": "1.11.1",
......
...@@ -4,9 +4,49 @@ ...@@ -4,9 +4,49 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c6e9f5bf77fc89c8660b540862019810", "content-hash": "96d54abdc29e1aeacfdc595d5d248fb3",
"packages": [ "packages": [
{ {
"name": "airwallex/payments-plugin-magento",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/airwallex/paymentacceptance-plugin-magento.git",
"reference": "38119a84cc0f9998d8c0d3b9b3e2f87a31dea8c7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/airwallex/paymentacceptance-plugin-magento/zipball/38119a84cc0f9998d8c0d3b9b3e2f87a31dea8c7",
"reference": "38119a84cc0f9998d8c0d3b9b3e2f87a31dea8c7",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"ext-json": "*",
"mobiledetect/mobiledetectlib": "^2.8"
},
"type": "magento2-module",
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Airwallex\\Payments\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"support": {
"issues": "https://github.com/airwallex/paymentacceptance-plugin-magento/issues",
"source": "https://github.com/airwallex/paymentacceptance-plugin-magento/tree/1.2.2"
},
"time": "2022-06-01T09:48:45+00:00"
},
{
"name": "aws/aws-crt-php", "name": "aws/aws-crt-php",
"version": "v1.0.2", "version": "v1.0.2",
"source": { "source": {
...@@ -4469,6 +4509,68 @@ ...@@ -4469,6 +4509,68 @@
] ]
}, },
{ {
"name": "mobiledetect/mobiledetectlib",
"version": "2.8.39",
"source": {
"type": "git",
"url": "https://github.com/serbanghita/Mobile-Detect.git",
"reference": "0fd6753003fc870f6e229bae869cc1337c99bc45"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/0fd6753003fc870f6e229bae869cc1337c99bc45",
"reference": "0fd6753003fc870f6e229bae869cc1337c99bc45",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=5.0.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8.35||~5.7"
},
"type": "library",
"autoload": {
"psr-0": {
"Detection": "namespaced/"
},
"classmap": [
"Mobile_Detect.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Serban Ghita",
"email": "serbanghita@gmail.com",
"homepage": "http://mobiledetect.net",
"role": "Developer"
}
],
"description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
"homepage": "https://github.com/serbanghita/Mobile-Detect",
"keywords": [
"detect mobile devices",
"mobile",
"mobile detect",
"mobile detector",
"php mobile detect"
],
"support": {
"issues": "https://github.com/serbanghita/Mobile-Detect/issues",
"source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.39"
},
"time": "2022-02-17T19:24:25+00:00"
},
{
"name": "monolog/monolog", "name": "monolog/monolog",
"version": "1.27.1", "version": "1.27.1",
"source": { "source": {
......
name: CI
on: [push]
jobs:
build:
runs-on: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Cache Composer dependencies
uses: actions/cache@v2
with:
path: /tmp/composer-cache
key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
- uses: php-actions/composer@v5
\ No newline at end of file
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Api\Data;
interface PaymentIntentInterface
{
public const TABLE = 'airwallex_payment_intents';
public const ID_COLUMN = 'id';
public const PAYMENT_INTENT_ID_COLUMN = 'payment_intent_id';
public const ORDER_INCREMENT_ID_COLUMN = 'order_increment_id';
/**
* @return mixed
*/
public function getId();
/**
* @return string
*/
public function getPaymentIntentId(): string;
/**
* @return string
*/
public function getOrderIncrementId(): string;
/**
* @param string $paymentIntentId
*
* @return $this
*/
public function setPaymentIntentId(string $paymentIntentId): self;
/**
* @param string $orderIncrementId
*
* @return $this
*/
public function setOrderIncrementId(string $orderIncrementId): self;
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Api;
interface ServiceInterface
{
/**
* @param string $method
*
* @return string
*/
public function createIntent(string $method): string;
/**
* @return string
*/
public function redirectUrl(): string;
/**
* @param string $intentId
* @param string $method
*
* @return string
*/
public function refreshIntent(string $intentId, string $method): string;
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Block\Adminhtml\Config;
use Magento\Config\Block\System\Config\Form\Fieldset as AdminhtmlFieldset;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Fieldset extends AdminhtmlFieldset
{
/**
* Add custom css class
*
* @param AbstractElement $element
* @return string
*/
protected function _getFrontendClass($element): string
{
return parent::_getFrontendClass($element) . ' with-button enabled';
}
/**
* Return header title part of html for payment solution
*
* @param AbstractElement $element
* @return string
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function _getHeaderTitleHtml($element): string
{
$html = '<div class="config-heading" >';
$htmlId = $element->getHtmlId();
$html .= '<div class="button-container"><button type="button"' .
' class="button action-configure' .
'" id="' .
$htmlId .
'-head" onclick="toggleSolution.call(this, \'' .
$htmlId .
"', '" .
$this->getUrl(
'adminhtml/*/state'
) . '\'); return false;"><span class="state-closed">' . __(
'Configure'
) . '</span><span class="state-opened">' . __(
'Close'
) . '</span></button>';
$html .= '</div>';
$html .= '<div class="heading"><strong>' . $element->getLegend() . '</strong>';
if ($comment = $element->getComment()) {
$html .= '<span class="heading-intro">' . $comment . '</span>';
}
$html .= '<div class="config-alt"></div>';
$html .= '</div></div>';
return $html;
}
/**
* Return header comment part of html for payment solution
*
* @param AbstractElement $element
* @return string
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function _getHeaderCommentHtml($element): string
{
return '';
}
/**
* Get collapsed state on-load
*
* @param AbstractElement $element
* @return false
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function _isCollapseState($element): bool
{
return false;
}
/**
* @param AbstractElement $element
* @return string
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function _getExtraJs($element): string
{
return '';
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Controller\Webhooks;
use Airwallex\Payments\Logger\Logger;
use Airwallex\Payments\Model\Webhook\Webhook;
use Exception;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\Request\Http as RequestHttp;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\Response\Http as ResponseHttp;
class Index implements HttpPostActionInterface, CsrfAwareActionInterface
{
private const JSON_DECODE_DEPTH = 512;
private const HTTP_OK = 200;
/**
* @var Webhook
*/
private Webhook $webhook;
/**
* @var RequestHttp
*/
private RequestHttp $request;
/**
* @var ResponseHttp
*/
private ResponseHttp $response;
/**
* @var Logger
*/
private Logger $logger;
/**
* Index constructor.
*
* @param Webhook $webhook
* @param RequestHttp $request
* @param ResponseHttp $response
* @param Logger $logger
*/
public function __construct(
Webhook $webhook,
RequestHttp $request,
ResponseHttp $response,
Logger $logger
) {
$this->webhook = $webhook;
$this->request = $request;
$this->response = $response;
$this->logger = $logger;
}
/**
* Get request from airwallex. Check request checksum for security. Each request parse and run webhook action
*
* @return ResponseHttp
* @throws \JsonException
*/
public function execute()
{
$data = json_decode($this->request->getContent(), false, self::JSON_DECODE_DEPTH, JSON_THROW_ON_ERROR);
try {
$this->webhook->checkChecksum($this->request);
if ($data->data) {
$this->webhook->dispatch($data->name, $data->data->object);
}
} catch (Exception $exception) {
$this->logger->addError($exception->getMessage());
}
return $this->response->setStatusCode(self::HTTP_OK);
}
/**
* @param RequestInterface $request
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return InvalidRequestException|null
*/
public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException
{
return null;
}
/**
* @param RequestInterface $request
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return bool|null
*/
public function validateForCsrf(RequestInterface $request): ?bool
{
return true;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Exception;
use Magento\Framework\Exception\LocalizedException;
class WebhookException extends LocalizedException
{
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Helper;
use Airwallex\Payments\Model\Client\Request\Authentication;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\ObjectManagerInterface;
class AuthenticationHelper
{
private const CACHE_NAME = 'airwallex_token';
/**
* @var CacheInterface
*/
private CacheInterface $cache;
/**
* @var ObjectManagerInterface
*/
private ObjectManagerInterface $objectManager;
/**
* AuthenticationHelper constructor.
*
* @param CacheInterface $cache
* @param ObjectManagerInterface $objectManager
*/
public function __construct(
CacheInterface $cache,
ObjectManagerInterface $objectManager
) {
$this->cache = $cache;
$this->objectManager = $objectManager;
}
/**
* @return string
*/
public function getBearerToken(): string
{
$token = $this->cache->load(self::CACHE_NAME);
if (empty($token)) {
$authenticationData = $this->objectManager->create(Authentication::class)->send();
$token = $authenticationData->token;
$cacheLifetime = $this->getCacheLifetime($authenticationData->expires_at);
$this->cache->save($token, self::CACHE_NAME, [], $cacheLifetime);
}
return $token;
}
/**
* Clear authentication token from cache.
*
* @return void
*/
public function clearToken()
{
$this->cache->remove(self::CACHE_NAME);
}
/**
* @param string $expiresAt
* @return int
* @throws \Exception
*/
protected function getCacheLifetime(string $expiresAt): int
{
$expiresAtDate = new \DateTime($expiresAt);
$currentDate = new \DateTime();
$currentDate->setTimezone($expiresAtDate->getTimezone());
return $expiresAtDate->getTimestamp() - $currentDate->getTimestamp();
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Helper;
use Airwallex\Payments\Model\Client\Request\AvailablePaymentMethods;
use Airwallex\Payments\Model\Methods\AbstractMethod;
use Exception;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Store\Model\StoreManagerInterface;
class AvailablePaymentMethodsHelper
{
private const CACHE_NAME = 'airwallex_payment_methods';
private const CACHE_TIME = 60;
private const METHOD_MAPPING = [
'wechat' => 'wechatpay'
];
/**
* @var AvailablePaymentMethods
*/
private AvailablePaymentMethods $availablePaymentMethod;
/**
* @var CacheInterface
*/
private CacheInterface $cache;
/**
* @var StoreManagerInterface
*/
private StoreManagerInterface $storeManager;
/**
* @var SerializerInterface
*/
private SerializerInterface $serializer;
/**
* @var Configuration
*/
private Configuration $configuration;
/**
* AvailablePaymentMethodsHelper constructor.
*
* @param AvailablePaymentMethods $availablePaymentMethod
* @param CacheInterface $cache
* @param SerializerInterface $serializer
* @param StoreManagerInterface $storeManager
* @param Configuration $configuration
*/
public function __construct(
AvailablePaymentMethods $availablePaymentMethod,
CacheInterface $cache,
SerializerInterface $serializer,
StoreManagerInterface $storeManager,
Configuration $configuration
) {
$this->availablePaymentMethod = $availablePaymentMethod;
$this->cache = $cache;
$this->storeManager = $storeManager;
$this->serializer = $serializer;
$this->configuration = $configuration;
}
/**
* @return bool
*/
public function canInitialize(): bool
{
return class_exists('Mobile_Detect') &&
!is_null($this->configuration->getApiKey()) &&
!is_null($this->configuration->getClientId());
}
/**
* @param string $code
*
* @return bool
*/
public function isAvailable(string $code): bool
{
$code = self::METHOD_MAPPING[$code] ?? $code;
return $this->canInitialize() && in_array($code, $this->getAllMethods(), true);
}
/**
* @return array
*/
private function getAllMethods(): array
{
$methods = $this->cache->load($this->getCacheName());
if ($methods) {
return $this->serializer->unserialize($methods);
}
try {
$methods = $this->availablePaymentMethod->setCurrency($this->getCurrencyCode())->send();
} catch (Exception $e) {
$methods = [];
}
$this->cache->save(
$this->serializer->serialize($methods),
$this->getCacheName(),
AbstractMethod::CACHE_TAGS,
self::CACHE_TIME
);
return $methods;
}
/**
* @return string
*/
private function getCacheName(): string
{
return self::CACHE_NAME . $this->getCurrencyCode();
}
/**
* @return string
*/
private function getCurrencyCode(): string
{
try {
return $this->storeManager->getStore()->getCurrentCurrency()->getCode();
} catch (Exception $exception) {
return '';
}
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Helper;
class CancelHelper
{
/**
* @var bool
*/
private bool $webhookCanceling = false;
/**
* @return bool
*/
public function isWebhookCanceling(): bool
{
return $this->webhookCanceling;
}
/**
* @param bool $webhookCanceling
*/
public function setWebhookCanceling(bool $webhookCanceling): void
{
$this->webhookCanceling = $webhookCanceling;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Helper;
use Airwallex\Payments\Model\Config\Source\Mode;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Payment\Model\MethodInterface;
class Configuration extends AbstractHelper
{
public const MODULE_NAME = 'Airwallex_Payments';
private const DEMO_BASE_URL = 'https://pci-api-demo.airwallex.com/api/v1/';
private const PRODUCTION_BASE_URL = 'https://pci-api.airwallex.com/api/v1/';
/**
* @return string|null
*/
public function getClientId(): ?string
{
return $this->scopeConfig->getValue('airwallex/general/' . $this->getMode() . '_client_id');
}
/**
* @return string|null
*/
public function getApiKey(): ?string
{
return $this->scopeConfig->getValue('airwallex/general/' . $this->getMode() . '_api_key');
}
/**
* @return bool
*/
public function isRequestLoggerEnable(): bool
{
return (bool) $this->scopeConfig->getValue('airwallex/general/request_logger');
}
/**
* @return string
*/
public function getWebhookSecretKey(): string
{
return $this->scopeConfig->getValue(
'airwallex/general/webhook_' . $this->getMode() . '_secret_key'
);
}
/**
* @return string
*/
public function getMode(): string
{
return $this->scopeConfig->getValue('airwallex/general/mode');
}
/**
* @return string
*/
public function getCardPaymentAction(): string
{
return $this->scopeConfig->getValue('payment/airwallex_payments_card/airwallex_payment_action');
}
/**
* @return string
*/
public function getApiUrl(): string
{
return $this->isDemoMode() ? self::DEMO_BASE_URL : self::PRODUCTION_BASE_URL;
}
/**
* @return bool
*/
private function isDemoMode(): bool
{
return $this->getMode() === Mode::DEMO;
}
/**
* @return bool
*/
public function isCaptureEnabled() {
return $this->scopeConfig->getValue('payment/airwallex_payments_card/airwallex_payment_action') === MethodInterface::ACTION_AUTHORIZE_CAPTURE;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Logger\Guzzle;
use Exception;
use GuzzleHttp\MessageFormatter as BaseMessageFormatter;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class MessageFormatter extends BaseMessageFormatter
{
private const WITHOUT_HEADERS = [
'Authorization',
'x-client-id',
'x-api-key'
];
/**
* Returns a formatted message string.
*
* @param RequestInterface $request Request that was sent
* @param ResponseInterface|null $response Response that was received
* @param \Throwable|null $error Exception that was received
*
* @return string
*/
public function format(
RequestInterface $request,
ResponseInterface $response = null,
\Throwable $error = null
): string {
foreach (self::WITHOUT_HEADERS as $header) {
$request = $request->withoutHeader($header);
}
return parent::format($request, $response, $error);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Logger\Guzzle;
use Airwallex\Payments\Helper\Configuration;
use Airwallex\Payments\Logger\Logger;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\FileSystemException;
use Monolog\Handler\StreamHandler;
class RequestLogger
{
private const FILE_NAME = 'airwallex_request.log';
/**
* @var Configuration
*/
private Configuration $configuration;
/**
* @var DirectoryList
*/
private DirectoryList $directoryList;
/**
* @var Logger
*/
private Logger $logger;
/**
* RequestLogger constructor.
*
* @param Configuration $configuration
* @param DirectoryList $directoryList
* @param Logger $logger
*/
public function __construct(Configuration $configuration, DirectoryList $directoryList, Logger $logger)
{
$this->configuration = $configuration;
$this->directoryList = $directoryList;
$this->logger = $logger;
}
/**
* @return HandlerStack
* @throws \Exception
*/
public function getStack(): HandlerStack
{
$stack = HandlerStack::create();
if (!$this->configuration->isRequestLoggerEnable()) {
return $stack;
}
$stack->push(Middleware::log(
(new Logger('Logger'))->pushHandler(new StreamHandler($this->getFileLocation())),
new MessageFormatter(MessageFormatter::DEBUG)
));
return $stack;
}
/**
* @return string
*/
private function getFileLocation(): string
{
try {
return $this->directoryList->getPath(DirectoryList::LOG) . DIRECTORY_SEPARATOR . self::FILE_NAME;
} catch (FileSystemException $exception) {
$this->logger->error($exception->getMessage());
}
return '';
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Logger;
use Magento\Framework\Logger\Handler\Base;
class Handler extends Base
{
/**
* Logging level
* @var int
*/
protected $loggerType = Logger::NOTICE;
/**
* File name
* @var string
*/
protected $fileName = '/var/log/airwallex_payments.log';
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Logger;
use Magento\Quote\Model\Quote;
use Magento\Sales\Model\Order;
use Monolog\Logger as BaseLogger;
class Logger extends BaseLogger
{
/**
* @param Quote $quote
* @param string $method
* @param string $message
*
* @return bool
*/
public function quoteError(Quote $quote, string $method, string $message): bool
{
$text = sprintf(
'%s Quote: %s - %s',
mb_strtoupper($method),
$quote->getId(),
$message
);
return $this->error($text);
}
/**
* @param Order $order
* @param string $method
* @param string $message
*
* @return bool
*/
public function orderError(Order $order, string $method, string $message): bool
{
$text = sprintf(
'%s Order: %s - %s',
mb_strtoupper($method),
$order->getIncrementId(),
$message
);
return $this->error($text);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Adminhtml\Notifications;
use Airwallex\Payments\Helper\AvailablePaymentMethodsHelper;
use Magento\Framework\Notification\MessageInterface;
class Dependencies implements MessageInterface
{
/**
* @var string|null
*/
private ?string $displayedText = null;
/**
* @var AvailablePaymentMethodsHelper
*/
private AvailablePaymentMethodsHelper $availablePaymentMethodsHelper;
/**
* Dependencies constructor.
*
* @param AvailablePaymentMethodsHelper $availablePaymentMethodsHelper
*/
public function __construct(AvailablePaymentMethodsHelper $availablePaymentMethodsHelper)
{
$this->availablePaymentMethodsHelper = $availablePaymentMethodsHelper;
$this->hasDependencies();
}
/**
* @return string
*/
public function getIdentity(): string
{
return 'airwallex_payments_notification_dependencies';
}
/**
* @return bool
*/
public function isDisplayed(): bool
{
return $this->displayedText !== null;
}
/**
* @return string
*/
public function getText(): string
{
return $this->displayedText;
}
/**
* @return int
*/
public function getSeverity(): int
{
return self::SEVERITY_MAJOR;
}
/**
* @return void
*/
private function hasDependencies(): void
{
if (!$this->availablePaymentMethodsHelper->canInitialize()) {
$this->displayedText = __('The Airwallex Payment module is missing dependency
Please run "composer require mobiledetect/mobiledetectlib" to install the dependency.');
}
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client;
use Airwallex\Payments\Helper\AuthenticationHelper;
use Airwallex\Payments\Helper\Configuration;
use Airwallex\Payments\Logger\Guzzle\RequestLogger;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Framework\DataObject\IdentityService;
use Magento\Framework\Module\ModuleListInterface;
use Psr\Http\Message\ResponseInterface;
abstract class AbstractClient
{
private const JSON_DECODE_DEPTH = 512;
private const SUCCESS_STATUS_START = 200;
private const SUCCESS_STATUS_END = 299;
private const AUTHENTICATION_FAILED = 401;
private const TIME_OUT = 30;
private const DEFAULT_HEADER = [
'Content-Type' => 'application/json',
'region' => 'string'
];
/**
* @var AuthenticationHelper
*/
private AuthenticationHelper $authenticationHelper;
/**
* @var IdentityService
*/
private IdentityService $identityService;
/**
* @var RequestLogger
*/
private RequestLogger $requestLogger;
/**
* @var Configuration
*/
protected Configuration $configuration;
/**
* @var ModuleListInterface
*/
protected ModuleListInterface $moduleList;
/**
* @var array
*/
private array $params = [];
/**
* AbstractClient constructor.
*
* @param AuthenticationHelper $authenticationHelper
* @param IdentityService $identityService
* @param RequestLogger $requestLogger
* @param Configuration $configuration
* @param ModuleListInterface $moduleList
*/
public function __construct(
AuthenticationHelper $authenticationHelper,
IdentityService $identityService,
RequestLogger $requestLogger,
Configuration $configuration,
ModuleListInterface $moduleList
) {
$this->authenticationHelper = $authenticationHelper;
$this->identityService = $identityService;
$this->requestLogger = $requestLogger;
$this->configuration = $configuration;
$this->moduleList = $moduleList;
}
/**
* @return mixed
* @throws GuzzleException
* @throws \JsonException
* @throws RequestException
*/
public function send()
{
$client = new Client([
'base_uri' => $this->configuration->getApiUrl(),
'timeout' => self::TIME_OUT,
'handler' => $this->requestLogger->getStack()
]);
$request = $this->createRequest($client);
$statusCode = $request->getStatusCode();
// If authorization fails on first try, clear token from cache and try again.
if ($statusCode === self::AUTHENTICATION_FAILED) {
$this->authenticationHelper->clearToken();
$request = $this->createRequest($client);
$statusCode = $request->getStatusCode();
}
// If still invalid response, process error.
if (!($statusCode >= self::SUCCESS_STATUS_START && $statusCode < self::SUCCESS_STATUS_END)) {
$response = $this->parseJson($request);
throw new RequestException($response->message);
}
return $this->parseResponse($request);
}
/**
* @param array $params
*
* @return $this
*/
protected function setParams(array $params): AbstractClient
{
$this->params = array_merge($this->params, $params);
return $this;
}
/**
* @param string $name
* @param string $value
*
* @return $this
*/
protected function setParam(string $name, string $value): AbstractClient
{
$this->params[$name] = $value;
return $this;
}
/**
* @return string
*/
protected function getMethod(): string
{
return 'POST';
}
/**
* @param ResponseInterface $request
*
* @return object
* @throws \JsonException
*/
protected function parseJson(ResponseInterface $request): object
{
return json_decode((string) $request->getBody(), false, self::JSON_DECODE_DEPTH, JSON_THROW_ON_ERROR);
}
/**
* Get options to create request.
*
* @return array
*/
protected function getRequestOptions(): array
{
return [
'headers' => array_merge(self::DEFAULT_HEADER, $this->getHeaders()),
'http_errors' => false
];
}
/**
* @return array
*/
protected function getHeaders(): array
{
$header = [];
if ($this instanceof BearerAuthenticationInterface) {
$header['Authorization'] = 'Bearer ' . $this->authenticationHelper->getBearerToken();
}
return $header;
}
/**
* Get information about Magento version executing the request.
*
* @return array
*/
protected function getReferrerData(): array
{
return [
'type' => 'magento',
'version' => $this->moduleList->getOne(Configuration::MODULE_NAME)['setup_version']
];
}
/**
* Create request to Airwallex.
*
* @param Client $client
* @return ResponseInterface
* @throws GuzzleException
*/
protected function createRequest(Client $client): ResponseInterface
{
$method = $this->getMethod();
$options = $this->getRequestOptions();
if ($method === 'POST') {
$this->params['request_id'] = $this->identityService->generateId();
$this->params['referrer_data'] = $this->getReferrerData();
$options['json'] = $this->params;
}
return $client->request($this->getMethod(), $this->getUri(), $options);
}
/**
* @return string
*/
abstract protected function getUri(): string;
/**
* @param ResponseInterface $request
*
* @return mixed
*/
abstract protected function parseResponse(ResponseInterface $request);
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Interfaces;
interface BearerAuthenticationInterface
{
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request;
use Airwallex\Payments\Model\Client\AbstractClient;
use JsonException;
use Psr\Http\Message\ResponseInterface;
class Authentication extends AbstractClient
{
private const X_API_VERSION = '2020-04-30';
/**
* @return string[]
*/
protected function getHeaders(): array
{
return [
'x-client-id' => $this->configuration->getClientId(),
'x-api-key' => $this->configuration->getApiKey(),
'x-api-version' => self::X_API_VERSION
];
}
/**
* @return string
*/
protected function getUri(): string
{
return 'authentication/login';
}
/**
* @param ResponseInterface $request
*
* @return object
* @throws JsonException
*/
protected function parseResponse(ResponseInterface $request): object
{
return $this->parseJson($request);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request;
use Airwallex\Payments\Model\Client\AbstractClient;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use Psr\Http\Message\ResponseInterface;
class AvailablePaymentMethods extends AbstractClient implements BearerAuthenticationInterface
{
private const TRANSACTION_MODE = 'oneoff';
/**
* @var string
*/
private string $currency;
/**
* @param string $currency
*
* @return $this
*/
public function setCurrency(string $currency): self
{
$this->currency = $currency;
return $this;
}
/**
* @return string
*/
protected function getUri(): string
{
$params = http_build_query([
'transaction_mode' => self::TRANSACTION_MODE,
'transaction_currency' => $this->currency,
'active' => true,
]);
return 'pa/config/payment_method_types?' . $params;
}
/**
* @return string
*/
protected function getMethod(): string
{
return 'GET';
}
/**
* @param ResponseInterface $request
*
* @return array
* @throws \JsonException
*/
protected function parseResponse(ResponseInterface $request): array
{
$response = $this->parseJson($request);
return array_map(static function (object $item) {
return $item->name;
}, $response->items);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request\PaymentIntents;
use Airwallex\Payments\Model\Client\AbstractClient;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use Psr\Http\Message\ResponseInterface;
class Cancel extends AbstractClient implements BearerAuthenticationInterface
{
/**
* @var string
*/
private string $paymentIntentId;
/**
* @param string $id
*
* @return $this
*/
public function setPaymentIntentId(string $id): self
{
$this->paymentIntentId = $id;
return $this;
}
/**
* @return string
*/
protected function getUri(): string
{
return 'pa/payment_intents/' . $this->paymentIntentId . '/cancel';
}
/**
* @param ResponseInterface $request
*
* @return object
* @throws \JsonException
*/
protected function parseResponse(ResponseInterface $request): object
{
return $this->parseJson($request);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request\PaymentIntents;
use Airwallex\Payments\Model\Client\AbstractClient;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use Psr\Http\Message\ResponseInterface;
class Capture extends AbstractClient implements BearerAuthenticationInterface
{
/**
* @var string
*/
private string $paymentIntentId;
/**
* @param string $id
*
* @return $this
*/
public function setPaymentIntentId(string $id): self
{
$this->paymentIntentId = $id;
return $this;
}
/**
* @param float $amount
*
* @return Capture
*/
public function setInformation(float $amount): self
{
return $this->setParams([
'amount' => $amount,
]);
}
/**
* @return string
*/
protected function getUri(): string
{
return 'pa/payment_intents/' . $this->paymentIntentId . '/capture';
}
/**
* @param ResponseInterface $request
*
* @return object
* @throws \JsonException
*/
protected function parseResponse(ResponseInterface $request): object
{
return $this->parseJson($request);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request\PaymentIntents;
use Airwallex\Payments\Model\Client\AbstractClient;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use Psr\Http\Message\ResponseInterface;
class Confirm extends AbstractClient implements BearerAuthenticationInterface
{
private const DESKTOP_FLOW = 'webqr';
private const MOBILE_FLOW = 'mweb';
/**
* @var string
*/
private string $paymentIntentId;
/**
* @param string $id
*
* @return $this
*/
public function setPaymentIntentId(string $id): self
{
$this->paymentIntentId = $id;
return $this;
}
/**
* @param string $method
* @param bool $isMobile
* @param string|null $osType
*
* @return Confirm
*/
public function setInformation(string $method, bool $isMobile, string $osType = null): self
{
$data = [
'type' => $method
];
$data[$method] = [
'flow' => $isMobile ? self::MOBILE_FLOW : self::DESKTOP_FLOW
];
if ($isMobile) {
$data[$method]['os_type'] = $osType;
}
return $this->setParams([
'payment_method' => $data
]);
}
/**
* @return string
*/
protected function getUri(): string
{
return 'pa/payment_intents/' . $this->paymentIntentId . '/confirm';
}
/**
* @param ResponseInterface $request
*
* @return string
* @throws \JsonException
*/
protected function parseResponse(ResponseInterface $request): string
{
$request = $this->parseJson($request);
return $request->next_action->url;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ('GPL') v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request\PaymentIntents;
use Airwallex\Payments\Model\Client\AbstractClient;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Item;
use Psr\Http\Message\ResponseInterface;
class Create extends AbstractClient implements BearerAuthenticationInterface
{
/**
* @param Quote $quote
* @param string $returnUrl
*
* @return AbstractClient|Create
*/
public function setQuote(Quote $quote, string $returnUrl): self
{
return $this->setParams([
'amount' => $quote->getBaseGrandTotal(),
'currency' => $quote->getQuoteCurrencyCode(),
'merchant_order_id' => $quote->getReservedOrderId(),
'supplementary_amount' => 1,
'return_url' => $returnUrl,
'order' => [
'products' => array_values(array_filter($this->getQuoteProducts($quote))),
'shipping' => $this->getShippingAddress($quote)
]
]);
}
/**
* @return string
*/
protected function getUri(): string
{
return 'pa/payment_intents/create';
}
/**
* @param ResponseInterface $request
*
* @return array
* @throws \JsonException
*/
protected function parseResponse(ResponseInterface $request): array
{
$data = $this->parseJson($request);
return [
'clientSecret' => $data->client_secret,
'id' => $data->id,
];
}
/**
* @param Quote $quote
*
* @return array|null
*/
private function getShippingAddress(Quote $quote): ?array
{
$shippingAddress = $quote->getShippingAddress();
if ($quote->getIsVirtual()) {
return null;
}
return [
'fist_name' => $shippingAddress->getName(),
'last_name' => $shippingAddress->getLastname(),
'phone_number' => $shippingAddress->getTelephone(),
'shipping_method' => $shippingAddress->getShippingMethod(),
'address' => [
'city' => $shippingAddress->getCity(),
'country_code' => $shippingAddress->getCountryId(),
'postcode' => $shippingAddress->getPostcode(),
'state' => $shippingAddress->getRegion(),
'street' => current($shippingAddress->getStreet()),
]
];
}
/**
* @param Quote $quote
*
* @return array
*/
private function getQuoteProducts(Quote $quote): array
{
return array_map(static function (Item $item) {
if ((float) $item->getPrice() === 0.0) {
return null;
}
$child = $item->getChildren();
$child = $child ? current($child) : null;
$name = $child ? $child->getName() : $item->getName();
return [
'code' => $item->getSku(),
'desc' => $name,
'name' => $name,
'quantity' => $item->getQty(),
'sku' => $item->getSku(),
'unit_price' => $item->getPrice(),
'url' => $item->getProduct()->getProductUrl()
];
}, $quote->getAllItems());
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client\Request\PaymentIntents;
use Airwallex\Payments\Model\Client\AbstractClient;
use Airwallex\Payments\Model\Client\Interfaces\BearerAuthenticationInterface;
use Psr\Http\Message\ResponseInterface;
class Refund extends AbstractClient implements BearerAuthenticationInterface
{
/**
* @param string $paymentIntentId
* @param float $amount
*
* @return Refund
*/
public function setInformation(string $paymentIntentId, float $amount): self
{
return $this->setParams([
'amount' => $amount,
'payment_intent_id' => $paymentIntentId
]);
}
/**
* @return string
*/
protected function getUri(): string
{
return 'pa/refunds/create';
}
/**
* @param ResponseInterface $request
*
* @return object
* @throws \JsonException
*/
protected function parseResponse(ResponseInterface $request): object
{
return $this->parseJson($request);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Client;
use RuntimeException;
class RequestException extends RuntimeException
{
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Config\Source;
use Magento\Framework\Data\OptionSourceInterface;
class Mode implements OptionSourceInterface
{
public const DEMO = 'demo';
private const PRODUCTION = 'prod';
/**
* @return array[]
*/
public function toOptionArray(): array
{
return [
[
'value' => self::DEMO,
'label' => __('Demo')
],
[
'value' => self::PRODUCTION,
'label' => __('Production')
],
];
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Config\Source;
use Magento\Framework\Data\OptionSourceInterface;
use Magento\Payment\Model\MethodInterface;
class PaymentAction implements OptionSourceInterface
{
/**
* @return array[]
*/
public function toOptionArray(): array
{
return [
[
'value' => MethodInterface::ACTION_AUTHORIZE,
'label' => __('Authorize Only')
],
[
'value' => MethodInterface::ACTION_AUTHORIZE_CAPTURE,
'label' => __('Authorize and Capture')
],
];
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Config\Source;
use Magento\Backend\Block\Template\Context;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Data\Form\Element\AbstractElement;
class WebhookUrl extends Field
{
private const WEBHOOK_PATH = 'airwallex/webhooks';
/**
* @var ScopeConfigInterface
*/
private ScopeConfigInterface $scopeConfig;
/**
* WebhookUrl constructor.
*
* @param ScopeConfigInterface $scopeConfig
* @param Context $context
* @param array $data
*/
public function __construct(
ScopeConfigInterface $scopeConfig,
Context $context,
array $data = []
) {
parent::__construct($context, $data);
$this->scopeConfig = $scopeConfig;
}
/**
* {@inheritDoc}
* @param AbstractElement $element
* @return string
*/
public function _getElementHtml(AbstractElement $element): string
{
$element->setValue($this->scopeConfig->getValue('web/secure/base_url') . self::WEBHOOK_PATH);
$element->setDisabled('disabled');
return parent::_getElementHtml($element);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Methods;
use Airwallex\Payments\Helper\AvailablePaymentMethodsHelper;
use Airwallex\Payments\Helper\CancelHelper;
use Airwallex\Payments\Model\Client\Request\PaymentIntents\Cancel;
use Airwallex\Payments\Model\Client\Request\PaymentIntents\Capture;
use Airwallex\Payments\Model\Client\Request\PaymentIntents\Confirm;
use Airwallex\Payments\Model\Client\Request\PaymentIntents\Refund;
use Airwallex\Payments\Model\PaymentIntentRepository;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Checkout\Helper\Data as CheckoutData;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Payment\Gateway\Command\CommandManagerInterface;
use Magento\Payment\Gateway\Command\CommandPoolInterface;
use Magento\Payment\Gateway\Config\ValueHandlerPoolInterface;
use Magento\Payment\Gateway\Data\PaymentDataObjectFactory;
use Magento\Payment\Gateway\Validator\ValidatorPoolInterface;
use Magento\Payment\Model\InfoInterface;
use Magento\Payment\Model\Method\Adapter;
use Magento\Quote\Api\Data\CartInterface;
use Psr\Log\LoggerInterface;
use RuntimeException;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
abstract class AbstractMethod extends Adapter
{
public const CACHE_TAGS = ['airwallex'];
public const PAYMENT_PREFIX = 'airwallex_payments_';
/**
* @var LoggerInterface|null
*/
protected $logger;
/**
* @var Refund
*/
private Refund $refund;
/**
* @var Capture
*/
protected Capture $capture;
/**
* @var PaymentIntentRepository
*/
private PaymentIntentRepository $paymentIntentRepository;
/**
* @var Cancel
*/
private Cancel $cancel;
/**
* @var CancelHelper
*/
private CancelHelper $cancelHelper;
/**
* @var AvailablePaymentMethodsHelper
*/
private AvailablePaymentMethodsHelper $availablePaymentMethodsHelper;
/**
* @var Confirm
*/
protected Confirm $confirm;
/**
* @var CheckoutData
*/
protected CheckoutData $checkoutHelper;
/**
* Payment constructor.
*
* @param ManagerInterface $eventManager
* @param ValueHandlerPoolInterface $valueHandlerPool
* @param PaymentDataObjectFactory $paymentDataObjectFactory
* @param string $code
* @param string $formBlockType
* @param string $infoBlockType
* @param Refund $refund
* @param Capture $capture
* @param Cancel $cancel
* @param Confirm $confirm
* @param CheckoutData $checkoutHelper
* @param AvailablePaymentMethodsHelper $availablePaymentMethodsHelper
* @param CancelHelper $cancelHelper
* @param PaymentIntentRepository $paymentIntentRepository
* @param CommandPoolInterface|null $commandPool
* @param ValidatorPoolInterface|null $validatorPool
* @param CommandManagerInterface|null $commandExecutor
* @param LoggerInterface|null $logger
*/
public function __construct(
ManagerInterface $eventManager,
ValueHandlerPoolInterface $valueHandlerPool,
PaymentDataObjectFactory $paymentDataObjectFactory,
$code,
$formBlockType,
$infoBlockType,
Refund $refund,
Capture $capture,
Cancel $cancel,
Confirm $confirm,
CheckoutData $checkoutHelper,
AvailablePaymentMethodsHelper $availablePaymentMethodsHelper,
CancelHelper $cancelHelper,
PaymentIntentRepository $paymentIntentRepository,
CommandPoolInterface $commandPool = null,
ValidatorPoolInterface $validatorPool = null,
CommandManagerInterface $commandExecutor = null,
LoggerInterface $logger = null
) {
parent::__construct(
$eventManager,
$valueHandlerPool,
$paymentDataObjectFactory,
$code,
$formBlockType,
$infoBlockType,
$commandPool,
$validatorPool,
$commandExecutor,
$logger
);
$this->logger = $logger;
$this->refund = $refund;
$this->capture = $capture;
$this->paymentIntentRepository = $paymentIntentRepository;
$this->cancel = $cancel;
$this->availablePaymentMethodsHelper = $availablePaymentMethodsHelper;
$this->cancelHelper = $cancelHelper;
$this->confirm = $confirm;
$this->checkoutHelper = $checkoutHelper;
}
/**
* @param DataObject $data
*
* @return $this
* @throws LocalizedException
*/
public function assignData(DataObject $data): self
{
$additionalData = $data->getData('additional_data');
if (isset($additionalData['intent_id'])) {
$info = $this->getInfoInstance();
$info->setAdditionalInformation('intent_id', $additionalData['intent_id']);
}
return $this;
}
/**
* @param InfoInterface $payment
* @param float $amount
*
* @return $this
* @throws AlreadyExistsException|LocalizedException
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function authorize(InfoInterface $payment, $amount): self
{
$intentId = $this->getIntentId();
$payment->setTransactionId($intentId);
$payment->setIsTransactionClosed(false);
$this->paymentIntentRepository->save(
$payment->getOrder()->getIncrementId(),
$intentId
);
return $this;
}
/**
* @param InfoInterface $payment
* @param float $amount
*
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function capture(InfoInterface $payment, $amount): self
{
return $this;
}
/**
* @param InfoInterface $payment
*
* @return $this
* @throws Exception
*/
public function cancel(InfoInterface $payment): self
{
if ($this->cancelHelper->isWebhookCanceling()) {
return $this;
}
$paymentTransactionId = str_replace(['-void', '-cancel'], '', $payment->getTransactionId());
try {
$this->cancel->setPaymentIntentId($paymentTransactionId)->send();
} catch (GuzzleException $exception) {
$this->logger->orderError($payment->getOrder(), 'cancel', $exception->getMessage());
throw new RuntimeException(__($exception->getMessage()));
}
return $this;
}
/**
* @param InfoInterface $payment
* @param float $amount
*
* @return $this
* @throws Exception
*/
public function refund(InfoInterface $payment, $amount): self
{
$paymentTransactionId = str_replace('-refund', '', $payment->getTransactionId());
$paymentTransactionId = str_replace('-capture', '', $paymentTransactionId);
try {
$this->refund
->setInformation($paymentTransactionId, $amount)
->send();
} catch (GuzzleException $exception) {
$this->logger->orderError($payment->getOrder(), 'refund', $exception->getMessage());
throw new RuntimeException(__($exception->getMessage()));
}
return $this;
}
/**
* @param InfoInterface $payment
*
* @return $this
* @throws Exception
*/
public function void(InfoInterface $payment): self
{
return $this->cancel($payment);
}
/**
* @param CartInterface|null $quote
*
* @return bool
*/
public function isAvailable(CartInterface $quote = null): bool
{
return parent::isAvailable($quote) &&
$this->availablePaymentMethodsHelper->isAvailable($this->getPaymentMethodCode());
}
/**
* @return string
* @throws LocalizedException
*/
protected function getIntentId(): string
{
return $this->getInfoInstance()->getAdditionalInformation('intent_id');
}
/**
* @return string
*/
protected function getPaymentMethodCode(): string
{
return str_replace(self::PAYMENT_PREFIX, '', $this->getCode());
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Methods;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Payment\Model\InfoInterface;
class CardMethod extends AbstractMethod
{
public const CODE = 'airwallex_payments_card';
/**
* @param InfoInterface $payment
* @param float $amount
*
* @return $this
* @throws LocalizedException
*/
public function capture(InfoInterface $payment, $amount): self
{
$intentId = $this->getIntentId();
$payment->setTransactionId($intentId);
try {
$this->capture
->setPaymentIntentId($intentId)
->setInformation($amount)
->send();
$this->logger->error(sprintf('Credit Card: Payment Intent %s, Capture information', $intentId));
} catch (GuzzleException $exception) {
$this->logger->orderError($payment->getOrder(), 'capture', $exception->getMessage());
}
return $this;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Methods;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Payment\Model\InfoInterface;
use Mobile_Detect;
use Exception;
class RedirectMethod extends AbstractMethod
{
public const DANA_CODE = 'airwallex_payments_dana';
public const ALIPAYCN_CODE = 'airwallex_payments_alipaycn';
public const ALIPAYHK_CODE = 'airwallex_payments_alipayhk';
public const GCASH_CODE = 'airwallex_payments_gcash';
public const KAKAO_CODE = 'airwallex_payments_kakaopay';
public const TOUCH_N_GO_CODE = 'airwallex_payments_tng';
/**
* @param InfoInterface $payment
* @param float $amount
*
* @return $this
* @throws GuzzleException
* @throws AlreadyExistsException
* @throws LocalizedException
*/
public function authorize(InfoInterface $payment, $amount): self
{
parent::authorize($payment, $amount);
$detect = new Mobile_Detect();
try {
$returnUrl = $this->confirm
->setPaymentIntentId($this->getIntentId())
->setInformation($this->getPaymentMethodCode(), $detect->isMobile(), $this->getMobileOS($detect))
->send();
} catch (Exception $exception) {
throw new LocalizedException(__($exception->getMessage()));
}
$this->checkoutHelper->getCheckout()->setAirwallexPaymentsRedirectUrl($returnUrl);
return $this;
}
/**
* @param Mobile_Detect $detect
*
* @return string|null
*/
private function getMobileOS(Mobile_Detect $detect): ?string
{
if (!$detect->isMobile()) {
return null;
}
return $detect->isAndroidOS() ? 'android' : 'ios';
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Methods;
class WechatMethod extends AbstractMethod
{
public const CODE = 'airwallex_payments_wechat';
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model;
use Airwallex\Payments\Api\Data\PaymentIntentInterface;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Model\AbstractModel;
use Airwallex\Payments\Model\ResourceModel\PaymentIntent as ResourcePaymentIntent;
class PaymentIntent extends AbstractModel implements IdentityInterface, PaymentIntentInterface
{
/**
* @return void
*/
public function _construct()
{
$this->_init(ResourcePaymentIntent::class);
}
/**
* @return string[]
*/
public function getIdentities(): array
{
return ['airwallex_payment_intents' . '_' . $this->getId()];
}
/**
* @return string
*/
public function getPaymentIntentId(): string
{
return $this->getData(PaymentIntentInterface::PAYMENT_INTENT_ID_COLUMN);
}
/**
* @return string
*/
public function getOrderIncrementId(): string
{
return $this->getData(PaymentIntentInterface::ORDER_INCREMENT_ID_COLUMN);
}
/**
* @param string $paymentIntentId
*
* @return PaymentIntentInterface
*/
public function setPaymentIntentId(string $paymentIntentId): PaymentIntentInterface
{
return $this->setData(PaymentIntentInterface::PAYMENT_INTENT_ID_COLUMN, $paymentIntentId);
}
/**
* @param string $orderIncrementId
*
* @return PaymentIntentInterface
*/
public function setOrderIncrementId(string $orderIncrementId): PaymentIntentInterface
{
return $this->setData(PaymentIntentInterface::ORDER_INCREMENT_ID_COLUMN, $orderIncrementId);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model;
use Airwallex\Payments\Api\Data\PaymentIntentInterface;
use Airwallex\Payments\Model\ResourceModel\PaymentIntent as PaymentIntentResource;
use Airwallex\Payments\Model\ResourceModel\PaymentIntent\CollectionFactory;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Sales\Api\Data\OrderInterface;
class PaymentIntentRepository
{
private const RACE_SLEEP_TIME = 4;
/**
* @var CollectionFactory
*/
private CollectionFactory $collectionFactory;
/**
* @var PaymentIntentFactory
*/
private PaymentIntentFactory $paymentIntentFactory;
/**
* @var PaymentIntentResource
*/
private PaymentIntentResource $paymentIntent;
/**
* @var OrderInterface
*/
private OrderInterface $order;
/**
* PaymentIntentRepository constructor.
*
* @param CollectionFactory $collectionFactory
* @param PaymentIntentFactory $paymentIntentFactory
* @param PaymentIntentResource $paymentIntent
* @param OrderInterface $order
*/
public function __construct(
CollectionFactory $collectionFactory,
PaymentIntentFactory $paymentIntentFactory,
PaymentIntentResource $paymentIntent,
OrderInterface $order
) {
$this->collectionFactory = $collectionFactory;
$this->paymentIntentFactory = $paymentIntentFactory;
$this->paymentIntent = $paymentIntent;
$this->order = $order;
}
/**
* Webhooks Race Condition: Sometimes we may receive the webhook before Magento commits the order to the database,
* so we give it a few seconds and try again. Can happen when multiple subscriptions are purchased together.
* @param string $paymentIntentId
* @param int $count
*
* @return OrderInterface|null
*/
public function loadOrderByPaymentIntent(string $paymentIntentId, int $count = 5): ?OrderInterface
{
$order = $this->getOrder($paymentIntentId);
if ($order === null || (empty($order->getId()) && $count >= 0)) {
// phpcs:ignore Magento2.Functions.DiscouragedFunction
sleep(self::RACE_SLEEP_TIME);
return $this->loadOrderByPaymentIntent($paymentIntentId, $count - 1);
}
return $order;
}
/**
* @param string $paymentIntentId
*
* @return OrderInterface|null
*/
public function getOrder(string $paymentIntentId): ?OrderInterface
{
$intentCollection = $this->collectionFactory->create();
/** @var PaymentIntentInterface|null $intent */
$intent = $intentCollection
->addFieldToFilter('payment_intent_id', ['eq' => $paymentIntentId])
->getFirstItem();
if ($intent->getId() === null) {
return null;
}
$order = $this->order->loadByIncrementId($intent->getOrderIncrementId());
return $order->getId() === null ? null : $order;
}
/**
* @param string $orderIncrement
* @param string $paymentIntentId
*
* @return void
* @throws AlreadyExistsException
*/
public function save(string $orderIncrement, string $paymentIntentId): void
{
$paymentIntent = $this->paymentIntentFactory->create();
$paymentIntent->setPaymentIntentId($paymentIntentId)
->setOrderIncrementId($orderIncrement);
$this->paymentIntent->save($paymentIntent);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model;
use Airwallex\Payments\Logger\Logger;
use Airwallex\Payments\Model\Client\Request\PaymentIntents\Create;
use Airwallex\Payments\Model\Client\Request\PaymentIntents\Cancel;
use Airwallex\Payments\Model\Methods\AbstractMethod;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Checkout\Model\Session;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\UrlInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteRepository;
/**
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class PaymentIntents
{
private const CACHE_TIME = 60;
/**
* @var Create
*/
private Create $paymentIntentsCreate;
/**
* @var Cancel
*/
private Cancel $paymentIntentsCancel;
/**
* @var Session
*/
private Session $checkoutSession;
/**
* @var CacheInterface
*/
private CacheInterface $cache;
/**
* @var SerializerInterface
*/
private SerializerInterface $serializer;
/**
* @var QuoteRepository
*/
private QuoteRepository $quoteRepository;
/**
* @var Logger
*/
private Logger $logger;
/**
* @var UrlInterface
*/
private UrlInterface $urlInterface;
public function __construct(
Create $paymentIntentsCreate,
Cancel $paymentIntentsCancel,
Session $checkoutSession,
SerializerInterface $serializer,
QuoteRepository $quoteRepository,
CacheInterface $cache,
UrlInterface $urlInterface,
Logger $logger
) {
$this->paymentIntentsCancel = $paymentIntentsCancel;
$this->paymentIntentsCreate = $paymentIntentsCreate;
$this->checkoutSession = $checkoutSession;
$this->cache = $cache;
$this->serializer = $serializer;
$this->quoteRepository = $quoteRepository;
$this->logger = $logger;
$this->urlInterface = $urlInterface;
}
/**
* @return array
* @throws GuzzleException
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function getIntents(): array
{
$quote = $this->checkoutSession->getQuote();
$cacheKey = $this->getCacheKey($quote);
if ($response = $this->cache->load($cacheKey)) {
return $this->serializer->unserialize($response);
}
$this->saveQuote($quote);
$returnUrl = $this->urlInterface->getUrl('checkout/onepage/success');
try {
$response = $this->paymentIntentsCreate
->setQuote($quote, $returnUrl)
->send();
} catch (GuzzleException $exception) {
$this->logger->quoteError($quote, 'intents', $exception->getMessage());
throw $exception;
}
$this->cache->save(
$this->serializer->serialize($response),
$cacheKey,
AbstractMethod::CACHE_TAGS,
self::CACHE_TIME
);
return $response;
}
/**
* @return void
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function removeIntents(): void
{
$this->cache->remove($this->getCacheKey($this->checkoutSession->getQuote()));
}
/**
* @param Quote $quote
*
* @return string
*/
private function getCacheKey(Quote $quote): string
{
return 'airwallex-intent-' . $quote->getId();
}
/**
* @param Quote $quote
*
* @return void
*/
private function saveQuote(Quote $quote): void
{
if (!$quote->getReservedOrderId()) {
$quote->reserveOrderId();
$this->quoteRepository->save($quote);
}
}
/**
* @param string $intentId
* @return mixed
* @throws GuzzleException
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws \JsonException
*/
public function cancelIntent(string $intentId) {
try {
$response = $this->paymentIntentsCancel
->setPaymentIntentId($intentId)
->send();
} catch (GuzzleException $exception) {
$quote = $this->checkoutSession->getQuote();
$this->logger->quoteError($quote, 'intents', $exception->getMessage());
throw $exception;
}
$this->removeIntents();
return $response;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\ResourceModel;
use Airwallex\Payments\Api\Data\PaymentIntentInterface;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class PaymentIntent extends AbstractDb
{
/**
* @return void
*/
protected function _construct()
{
$this->_init(PaymentIntentInterface::TABLE, PaymentIntentInterface::ID_COLUMN);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\ResourceModel\PaymentIntent;
use Airwallex\Payments\Model\PaymentIntent;
use Airwallex\Payments\Model\ResourceModel\PaymentIntent as ResourcePaymentIntent;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
class Collection extends AbstractCollection
{
/**
* @return void
*/
protected function _construct()
{
$this->_init(PaymentIntent::class, ResourcePaymentIntent::class);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model;
use Airwallex\Payments\Api\ServiceInterface;
use Airwallex\Payments\Helper\Configuration;
use Airwallex\Payments\Model\Methods\CardMethod;
use GuzzleHttp\Exception\GuzzleException;
use Magento\Checkout\Helper\Data as CheckoutData;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Payment\Model\MethodInterface;
use Zend_Json;
class Service implements ServiceInterface
{
/**
* @var PaymentIntents
*/
private PaymentIntents $paymentIntents;
/**
* @var Configuration
*/
private Configuration $configuration;
/**
* @var CheckoutData
*/
private CheckoutData $checkoutHelper;
/**
* Index constructor.
*
* @param PaymentIntents $paymentIntents
* @param Configuration $configuration
* @param CheckoutData $checkoutHelper
*/
public function __construct(
PaymentIntents $paymentIntents,
Configuration $configuration,
CheckoutData $checkoutHelper
) {
$this->paymentIntents = $paymentIntents;
$this->configuration = $configuration;
$this->checkoutHelper = $checkoutHelper;
}
/**
* @param string $method
*
* @return string
* @throws GuzzleException
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function createIntent(string $method): string
{
$response = $this->paymentIntents->getIntents();
$response['mode'] = $this->configuration->getMode();
$response = array_merge($response, $this->getExtraConfiguration($method));
return Zend_Json::encode($response);
}
/**
* Return URL
*
* @return string
* @throws LocalizedException
*/
public function redirectUrl(): string
{
$checkout = $this->checkoutHelper->getCheckout();
if (empty($checkout->getLastRealOrderId())) {
throw new LocalizedException(__("Sorry, the order could not be placed. Please contact us for more help."));
}
return $checkout->getAirwallexPaymentsRedirectUrl();
}
/**
* @param string $method
*
* @return array
*/
private function getExtraConfiguration(string $method): array
{
$data = [];
if ($method === CardMethod::CODE) {
$paymentAction = $this->configuration->getCardPaymentAction();
$data['card']['auto_capture'] = $paymentAction === MethodInterface::ACTION_AUTHORIZE_CAPTURE;
}
return $data;
}
/**
* @param string $intentId
* @param string $method
* @return string
* @throws GuzzleException
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws \JsonException
*/
public function refreshIntent(string $intentId, string $method): string
{
$this->paymentIntents->cancelIntent($intentId);
return $this->createIntent($method);
}
}
<?php
namespace Airwallex\Payments\Model\Ui;
use Airwallex\Payments\Helper\Configuration;
use \Magento\Checkout\Model\ConfigProviderInterface;
class ConfigProvider implements ConfigProviderInterface
{
/**
* @var Configuration
*/
protected $configuration;
/**
* ConfigProvider constructor.
* @param Configuration $configuration
*/
public function __construct(
Configuration $configuration
) {
$this->configuration = $configuration;
}
/**
* Adds mode to checkout config array
*
* @return \array[][]
*/
public function getConfig()
{
$config = [
'payment' => [
'airwallex_payments' => [
'mode' => $this->configuration->getMode(),
'cc_auto_capture' => $this->configuration->isCaptureEnabled()
]
]
];
return $config;
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Webhook;
use Airwallex\Payments\Model\PaymentIntentRepository;
use Magento\Sales\Model\OrderRepository;
abstract class AbstractWebhook
{
/**
* @var OrderRepository
*/
protected OrderRepository $orderRepository;
/**
* @var PaymentIntentRepository
*/
protected PaymentIntentRepository $paymentIntentRepository;
/**
* AbstractWebhook constructor.
*
* @param OrderRepository $orderRepository
* @param PaymentIntentRepository $paymentIntentRepository
*/
public function __construct(
OrderRepository $orderRepository,
PaymentIntentRepository $paymentIntentRepository
) {
$this->orderRepository = $orderRepository;
$this->paymentIntentRepository = $paymentIntentRepository;
}
/**
* @param object $data
*
* @return void
*/
abstract public function execute(object $data): void;
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Webhook;
use Airwallex\Payments\Exception\WebhookException;
use Airwallex\Payments\Helper\CancelHelper;
use Airwallex\Payments\Model\PaymentIntentRepository;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Sales\Model\OrderRepository;
class Cancel extends AbstractWebhook
{
public const WEBHOOK_NAME = 'payment_attempt.cancelled';
/**
* @var CancelHelper
*/
private CancelHelper $cancelHelper;
/**
* Cancel constructor.
*
* @param OrderRepository $orderRepository
* @param PaymentIntentRepository $paymentIntentRepository
* @param CancelHelper $cancelHelper
*/
public function __construct(
OrderRepository $orderRepository,
PaymentIntentRepository $paymentIntentRepository,
CancelHelper $cancelHelper
) {
parent::__construct($orderRepository, $paymentIntentRepository);
$this->cancelHelper = $cancelHelper;
}
/**
* @param object $data
*
* @return void
* @throws AlreadyExistsException
* @throws InputException
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws WebhookException
*/
public function execute(object $data): void
{
$paymentIntent = $data->payment_intent_id;
$order = $this->paymentIntentRepository->getOrder($paymentIntent);
if ($order === null) {
throw new WebhookException(__('Can\'t find order %s', $paymentIntent));
}
if (!$order->canCancel()) {
throw new WebhookException(__('Can\'t cancel order %s', $paymentIntent));
}
$this->cancelHelper->setWebhookCanceling(true);
$order->cancel();
$this->orderRepository->save($order);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Webhook;
use Airwallex\Payments\Exception\WebhookException;
use Airwallex\Payments\Model\PaymentIntentRepository;
use Magento\Framework\DB\TransactionFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Sales\Model\Order\Invoice;
use Magento\Sales\Model\OrderRepository;
use Magento\Sales\Model\Service\InvoiceService;
class Capture extends AbstractWebhook
{
public const WEBHOOK_NAME = 'payment_attempt.capture_requested';
/**
* @var InvoiceService
*/
private InvoiceService $invoiceService;
/**
* @var TransactionFactory
*/
private TransactionFactory $transactionFactory;
/**
* Capture constructor.
*
* @param OrderRepository $orderRepository
* @param PaymentIntentRepository $paymentIntentRepository
* @param InvoiceService $invoiceService
* @param TransactionFactory $transactionFactory
*/
public function __construct(
OrderRepository $orderRepository,
PaymentIntentRepository $paymentIntentRepository,
InvoiceService $invoiceService,
TransactionFactory $transactionFactory
) {
parent::__construct($orderRepository, $paymentIntentRepository);
$this->invoiceService = $invoiceService;
$this->transactionFactory = $transactionFactory;
}
/**
* @param object $data
*
* @return void
* @throws LocalizedException
*/
public function execute(object $data): void
{
$order = $this->paymentIntentRepository->loadOrderByPaymentIntent($data->payment_intent_id);
if ($order === null) {
throw new WebhookException(__('Payment Intent: ' . $data->payment_intent_id . ': Can\'t find Order'));
}
$paid = $order->getBaseGrandTotal() - $order->getBaseTotalPaid();
if ($paid === 0.0) {
return;
}
$amount = $data->captured_amount;
$invoice = $this->invoiceService->prepareInvoice($order);
$invoice->setSubtotal($amount);
$invoice->setBaseSubtotal($amount);
$invoice->setGrandTotal($amount);
$invoice->setTransactionId($data->payment_intent_id);
$invoice->setBaseGrandTotal($amount);
$invoice->setRequestedCaptureCase(Invoice::CAPTURE_OFFLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(false);
$invoice->getOrder()->setIsInProcess(true);
$transactionSave = $this->transactionFactory->create()
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Webhook;
use Airwallex\Payments\Exception\WebhookException;
use Airwallex\Payments\Model\PaymentIntentRepository;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\CreditmemoFactory;
use Magento\Sales\Model\OrderRepository;
use Magento\Sales\Model\Service\CreditmemoService;
class Refund extends AbstractWebhook
{
public const WEBHOOK_ACCEPTED_NAME = 'refund.accepted';
public const WEBHOOK_SUCCESS_NAME = 'refund.succeeded';
/**
* @var CreditmemoFactory
*/
private CreditmemoFactory $creditmemoFactory;
/**
* @var CreditmemoService
*/
private CreditmemoService $creditmemoService;
/**
* Refund constructor.
*
* @param OrderRepository $orderRepository
* @param PaymentIntentRepository $paymentIntentRepository
* @param CreditmemoFactory $creditmemoFactory
* @param CreditmemoService $creditmemoService
*/
public function __construct(
OrderRepository $orderRepository,
PaymentIntentRepository $paymentIntentRepository,
CreditmemoFactory $creditmemoFactory,
CreditmemoService $creditmemoService
) {
parent::__construct($orderRepository, $paymentIntentRepository);
$this->creditmemoFactory = $creditmemoFactory;
$this->creditmemoService = $creditmemoService;
}
/**
* @param object $data
*
* @return void
* @throws AlreadyExistsException
* @throws InputException
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws WebhookException
*/
public function execute(object $data): void
{
$order = $this->paymentIntentRepository->getOrder($data->payment_intent_id);
if ($order === null) {
throw new WebhookException(__('Can\'t find order'));
}
if ($order->getState() === Order::STATE_HOLDED && $order->canUnhold()) {
$order->unhold();
}
if (!$order->canCreditmemo()) {
if ($order->canCancel()) {
$order->cancel();
$this->orderRepository->save($order);
}
return;
}
$this->createCreditMemo($order, $data->amount, $data->reason);
}
/**
* @param Order $order
* @param float $refundAmount
* @param string $reason
*
* @return void
* @throws LocalizedException
*/
private function createCreditMemo(Order $order, float $refundAmount, string $reason): void
{
$invoice = $order->getInvoiceCollection()->getFirstItem();
if ($invoice === null) {
return;
}
$baseToOrderRate = $order->getBaseToOrderRate();
$baseTotalNotRefunded = $order->getBaseGrandTotal() - $order->getBaseTotalRefunded();
$creditMemo = $this->creditmemoFactory->createByOrder($order);
$creditMemo->setInvoice($invoice);
if ($baseTotalNotRefunded > $refundAmount) {
$baseDiff = $baseTotalNotRefunded - $refundAmount;
$creditMemo->setAdjustmentPositive($baseDiff);
}
$creditMemo->setBaseGrandTotal($refundAmount);
$creditMemo->setGrandTotal($refundAmount * $baseToOrderRate);
$this->creditmemoService->refund($creditMemo, true);
$order->addCommentToStatusHistory(__('Order refunded through Airwallex, Reason: %1', $reason));
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Model\Webhook;
use Airwallex\Payments\Exception\WebhookException;
use Airwallex\Payments\Helper\Configuration;
use Magento\Framework\App\Request\Http;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use stdClass;
class Webhook
{
private const HASH_ALGORITHM = 'sha256';
/**
* @var Refund
*/
private Refund $refund;
/**
* @var Configuration
*/
private Configuration $configuration;
/**
* @var Capture
*/
private Capture $capture;
/**
* @var Cancel
*/
private Cancel $cancel;
/**
* Webhook constructor.
*
* @param Configuration $configuration
* @param Refund $refund
* @param Capture $capture
* @param Cancel $cancel
*/
public function __construct(Configuration $configuration, Refund $refund, Capture $capture, Cancel $cancel)
{
$this->refund = $refund;
$this->configuration = $configuration;
$this->capture = $capture;
$this->cancel = $cancel;
}
/**
* @param Http $request
*
* @return void
* @throws WebhookException
*/
public function checkChecksum(Http $request): void
{
$signature = $request->getHeader('x-signature');
$data = $request->getHeader('x-timestamp') . $request->getContent();
if (hash_hmac(self::HASH_ALGORITHM, $data, $this->configuration->getWebhookSecretKey()) !== $signature) {
throw new WebhookException(__('failed to verify the signature'));
}
}
/**
* @param string $type
* @param stdClass $data
*
* @return void
* @throws AlreadyExistsException
* @throws InputException
* @throws LocalizedException
* @throws NoSuchEntityException
* @throws WebhookException
*/
public function dispatch(string $type, stdClass $data): void
{
if (in_array($type, [Refund::WEBHOOK_ACCEPTED_NAME, Refund::WEBHOOK_SUCCESS_NAME], true)) {
$this->refund->execute($data);
}
if ($type === Capture::WEBHOOK_NAME) {
$this->capture->execute($data);
}
if ($type === Cancel::WEBHOOK_NAME) {
$this->cancel->execute($data);
}
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Observer;
use Airwallex\Payments\Model\PaymentIntents;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
class ClearSavedIntent implements ObserverInterface
{
/**
* @var PaymentIntents
*/
private PaymentIntents $paymentIntents;
/**
* ClearSavedIntent constructor.
*
* @param PaymentIntents $paymentIntents
*/
public function __construct(PaymentIntents $paymentIntents)
{
$this->paymentIntents = $paymentIntents;
}
/**
* @param Observer $observer
*
* @return void
* @throws LocalizedException
* @throws NoSuchEntityException
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function execute(Observer $observer): void
{
$this->paymentIntents->removeIntents();
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Plugin;
use Airwallex\Payments\Model\Methods\AbstractMethod;
use Magento\Payment\Block\Form\Container;
use Magento\Payment\Model\MethodInterface;
class RemoveMethodsFromAdminReorder
{
/**
* @param Container $subject
* @param array $results
*
* @return array
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterGetMethods(Container $subject, array $results): array
{
$results = array_filter($results, static function (MethodInterface $method) {
return strpos($method->getCode(), AbstractMethod::PAYMENT_PREFIX) === false;
});
return array_values($results);
}
}
<?php
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Airwallex\Payments\Plugin;
use Airwallex\Payments\Model\PaymentIntents;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
class StorePlugin
{
/**
* @var PaymentIntents
*/
private PaymentIntents $paymentIntents;
/**
* ClearSavedIntent constructor.
*
* @param PaymentIntents $paymentIntents
*/
public function __construct(PaymentIntents $paymentIntents)
{
$this->paymentIntents = $paymentIntents;
}
/**
* @return void
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function afterSetCurrentCurrencyCode(): void
{
$this->paymentIntents->removeIntents();
}
}
{
"name": "airwallex/payments-plugin-magento",
"type": "magento2-module",
"description": "",
"version": "1.2.2",
"require": {
"ext-json": "*",
"mobiledetect/mobiledetectlib": "^2.8"
},
"autoload": {
"files": [ "registration.php" ],
"psr-4": {
"Airwallex\\Payments\\": ""
}
}
}
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Config\Model\Config\TypePool">
<arguments>
<argument name="sensitive" xsi:type="array">
<item name="airwallex/general/demo_api_key" xsi:type="string">1</item>
<item name="airwallex/general/prod_api_key" xsi:type="string">1</item>
<item name="airwallex/general/webhook_prod_secret_key" xsi:type="string">1</item>
<item name="airwallex/general/webhook_demo_secret_key" xsi:type="string">1</item>
</argument>
</arguments>
</type>
<type name="Magento\Framework\Notification\MessageList">
<arguments>
<argument name="messages" xsi:type="array">
<item name="AirwallexDependenciesNotification" xsi:type="string">Airwallex\Payments\Model\Adminhtml\Notifications\Dependencies</item>
</argument>
</arguments>
</type>
</config>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="payment">
<group id="airwallex_payments" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Airwallex</label>
<comment>Airwallex provides you with the payment methods your customers trust and choose, from international cards to popular local payment methods</comment>
<fieldset_css>complex airwallex-admin-config</fieldset_css>
<frontend_model>Airwallex\Payments\Block\Adminhtml\Config\Fieldset</frontend_model>
<attribute type="displayIn">recommended_solutions</attribute>
<include path="Airwallex_Payments::system/basic.xml"/>
<include path="Airwallex_Payments::system/card.xml"/>
<include path="Airwallex_Payments::system/wechat.xml"/>
<include path="Airwallex_Payments::system/redirect.xml"/>
</group>
</section>
</system>
</config>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="basic" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Basic Settings</label>
<field id="mode" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Mode</label>
<source_model>Airwallex\Payments\Model\Config\Source\Mode</source_model>
<config_path>airwallex/general/mode</config_path>
</field>
<field id="demo_client_id" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Demo Client ID</label>
<config_path>airwallex/general/demo_client_id</config_path>
<depends>
<field id="mode">demo</field>
</depends>
</field>
<field id="demo_api_key" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Demo API Key</label>
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
<config_path>airwallex/general/demo_api_key</config_path>
<depends>
<field id="mode">demo</field>
</depends>
</field>
<field id="webhook_demo_secret_key" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Webhook Demo Secret Key</label>
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
<config_path>airwallex/general/webhook_demo_secret_key</config_path>
<depends>
<field id="mode">demo</field>
</depends>
</field>
<field id="prod_client_id" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Production Client ID</label>
<config_path>airwallex/general/prod_client_id</config_path>
<depends>
<field id="mode">prod</field>
</depends>
</field>
<field id="prod_api_key" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Production API Key</label>
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
<config_path>airwallex/general/prod_api_key</config_path>
<depends>
<field id="mode">prod</field>
</depends>
</field>
<field id="webhook_prod_secret_key" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Webhook Production Secret Key</label>
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
<config_path>airwallex/general/webhook_prod_secret_key</config_path>
<depends>
<field id="mode">prod</field>
</depends>
</field>
<field id="webhook_url" translate="label" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Webhook Url</label>
<frontend_model>Airwallex\Payments\Model\Config\Source\WebhookUrl</frontend_model>
</field>
<field id="request_logger" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Request Logger</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>airwallex/general/request_logger</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="card" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Credit Card</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_card/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_card/title</config_path>
</field>
<field id="airwallex_payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Payment Action</label>
<source_model>Airwallex\Payments\Model\Config\Source\PaymentAction</source_model>
<config_path>payment/airwallex_payments_card/airwallex_payment_action</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_card/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_card/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_card/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="redirect" translate="label" type="text" sortOrder="16" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Other Payment Methods</label>
<include path="Airwallex_Payments::system/redirect/alipaycn.xml"/>
<include path="Airwallex_Payments::system/redirect/alipayhk.xml"/>
<include path="Airwallex_Payments::system/redirect/dana.xml"/>
<include path="Airwallex_Payments::system/redirect/gcash.xml"/>
<include path="Airwallex_Payments::system/redirect/kakao.xml"/>
<include path="Airwallex_Payments::system/redirect/touch_n_go.xml"/>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="alipay_cn" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Alipay CN</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_alipaycn/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_alipaycn/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_alipaycn/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_alipaycn/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_alipaycn/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="alipay_hk" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Alipay HK</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_alipayhk/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_alipayhk/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_alipayhk/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_alipayhk/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_alipayhk/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="dana" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Dana</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_dana/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_dana/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_dana/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_dana/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_dana/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="gcash" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>GCash</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_gcash/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_gcash/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_gcash/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_gcash/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_gcash/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="kakao" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Kakao Pay</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_kakaopay/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_kakaopay/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_kakaopay/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_kakaoairwallex_payments_kakaopay/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_kakaopay/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="touch_n_go" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Touch ‘n Go</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_tng/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_tng/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_tng/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_tng/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_tng/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<include xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_include.xsd">
<group id="wechat" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>WeChat</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<config_path>payment/airwallex_payments_wechat/active</config_path>
</field>
<field id="title" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
<comment><![CDATA[This is the payment method title used at the checkout page]]></comment>
<config_path>payment/airwallex_payments_wechat/title</config_path>
</field>
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Payment From Applicable Countries</label>
<source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
<config_path>payment/airwallex_payments_wechat/allowspecific</config_path>
</field>
<field id="specificcountry" translate="label comment" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Display Payment Method For</label>
<comment><![CDATA[Select the countries and currencies for which Airwallex is available at the checkout.]]></comment>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<config_path>payment/airwallex_payments_wechat/specificcountry</config_path>
<depends>
<field id="allowspecific">1</field>
</depends>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sort Order</label>
<comment>Adjust this to move the payment method above or below other payment methods</comment>
<frontend_class>validate-number</frontend_class>
<config_path>payment/airwallex_payments_wechat/sort_order</config_path>
</field>
</group>
</include>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<airwallex>
<general>
<mode>demo</mode>
<demo_client_id />
<demo_api_key backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
<prod_client_id />
<prod_api_key backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
<webhook_demo_secret_key backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
<webhook_prod_secret_key backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
</general>
</airwallex>
<payment>
<airwallex_payments_card>
<active>0</active>
<model>AirwallexPaymentsCardsGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Card (Airwallex)</title>
<payment_action>authorize</payment_action>
<airwallex_payment_action>authorize_capture</airwallex_payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<can_save_cc>0</can_save_cc>
<sort_order>10</sort_order>
</airwallex_payments_card>
<airwallex_payments_wechat>
<active>0</active>
<model>AirwallexPaymentsWechatGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Wechat (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>20</sort_order>
</airwallex_payments_wechat>
<airwallex_payments_alipaycn>
<active>0</active>
<model>AirwallexPaymentsAlipayCNGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Alipay CN (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>30</sort_order>
</airwallex_payments_alipaycn>
<airwallex_payments_dana>
<active>0</active>
<model>AirwallexPaymentsDanaGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Dana (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>40</sort_order>
</airwallex_payments_dana>
<airwallex_payments_alipayhk>
<active>0</active>
<model>AirwallexPaymentsAlipayHKGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Alipay HK (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>50</sort_order>
</airwallex_payments_alipayhk>
<airwallex_payments_gcash>
<active>0</active>
<model>AirwallexPaymentsGCashGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by GCash (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>60</sort_order>
</airwallex_payments_gcash>
<airwallex_payments_kakaopay>
<active>0</active>
<model>AirwallexPaymentsKakaoGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Kakao (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>70</sort_order>
</airwallex_payments_kakaopay>
<airwallex_payments_tng>
<active>0</active>
<model>AirwallexPaymentsTouchNGoGatewayFacade</model>
<allowspecific>0</allowspecific>
<title>Pay by Touch ‘n Go (Airwallex)</title>
<payment_action>authorize</payment_action>
<is_gateway>1</is_gateway>
<can_authorize>1</can_authorize>
<can_capture>1</can_capture>
<can_capture_partial>0</can_capture_partial>
<can_refund>1</can_refund>
<can_refund_partial_per_invoice>1</can_refund_partial_per_invoice>
<can_void>1</can_void>
<can_cancel>1</can_cancel>
<can_use_internal>1</can_use_internal>
<can_use_checkout>1</can_use_checkout>
<sort_order>80</sort_order>
</airwallex_payments_tng>
</payment>
</default>
</config>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp/etc/csp_whitelist.xsd">
<policies>
<policy id="script-src">
<values>
<value id="airwallex-api" type="host">checkout.airwallex.com</value>
<value id="metrix" type="host">h.online-metrix.net/</value>
</values>
</policy>
<policy id="connect-src">
<values>
<value id="airwallex-api" type="host">checkout.airwallex.com</value>
<value id="metrix" type="host">h.online-metrix.net/</value>
</values>
</policy>
<policy id="frame-src">
<values>
<value id="airwallex-api" type="host">checkout.airwallex.com</value>
<value id="airwallex-demo-api" type="host">checkout-demo.airwallex.com</value>
<value id="metrix" type="host">h.online-metrix.net/</value>
<value id="pci-api-demo-airwallex" type="host">pci-api-demo.airwallex.com</value>
<value id="demo-pacybsmock-airwallex" type="host">demo-pacybsmock.airwallex.com</value>
</values>
</policy>
<policy id="img-src">
<values>
<value id="metrix" type="host">*.online-metrix.net/</value>
</values>
</policy>
</policies>
</csp_whitelist>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Magebit Lichtkoning module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2020 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="airwallex_payment_intents">
<column xsi:type="int" name="id" padding="6" unsigned="false" nullable="false" identity="true" />
<column xsi:type="varchar" name="order_increment_id" nullable="false" />
<column xsi:type="varchar" name="payment_intent_id" nullable="false" />
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id"/>
</constraint>
</table>
</schema>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_quote_add_item">
<observer name="after_add_quote_clear_saved_intent_from_cache" instance="Airwallex\Payments\Observer\ClearSavedIntent"/>
</event>
<event name="checkout_onepage_controller_success_action">
<observer name="quote_success_clear_saved_intent_from_cache" instance="Airwallex\Payments\Observer\ClearSavedIntent"/>
</event>
</config>
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Model\CompositeConfigProvider">
<arguments>
<argument name="configProviders" xsi:type="array">
<item name="airwallex_payments_config_provider" xsi:type="object">Airwallex\Payments\Model\Ui\ConfigProvider</item>
</argument>
</arguments>
</type>
</config>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="airwallex_payments" frontName="airwallex">
<module name="Airwallex_Payments" />
</route>
</router>
</config>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Airwallex_Payments" setup_version="1.2.2">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Payment"/>
<module name="Magento_Checkout"/>
</sequence>
</module>
</config>
<?xml version="1.0"?>
<!--
/**
* This file is part of the Airwallex Payments module.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade
* to newer versions in the future.
*
* @copyright Copyright (c) 2021 Magebit, Ltd. (https://magebit.com/)
* @license GNU General Public License ("GPL") v3.0
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-->
<payment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Payment:etc/payment.xsd">
<methods>
<method name="airwallex_payments">
<allow_multiple_address>1</allow_multiple_address>
</method>
</methods>
</payment>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment