diff --git a/Block/Adminhtml/Form/Field/RedirectUrl.php b/Block/Adminhtml/Form/Field/RedirectUrl.php
new file mode 100755
index 0000000..945f441
--- /dev/null
+++ b/Block/Adminhtml/Form/Field/RedirectUrl.php
@@ -0,0 +1,51 @@
+_storeManager->getStores();
+ $valueReturn = '';
+ $urlArray = [];
+
+ foreach ($stores as $store) {
+ $baseUrl = $store->getBaseUrl(UrlInterface::URL_TYPE_WEB, true);
+ if ($baseUrl) {
+ $value = $baseUrl . 'tendopay/standard/success/';
+ $urlArray[] = "
" . $this->escapeHtml($value) . "
";
+ }
+ }
+
+ $urlArray = array_unique($urlArray);
+ foreach ($urlArray as $uniqueUrl) {
+ $valueReturn .= "" . $uniqueUrl . "
";
+ }
+
+ return '' . $valueReturn . ' | ';
+ }
+
+ /**
+ * Render element value
+ *
+ * @param AbstractElement $element
+ * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ protected function _renderInheritCheckbox(AbstractElement $element)
+ {
+ return ' | ';
+ }
+}
diff --git a/Block/Adminhtml/Payment/Info.php b/Block/Adminhtml/Payment/Info.php
new file mode 100755
index 0000000..aa71c42
--- /dev/null
+++ b/Block/Adminhtml/Payment/Info.php
@@ -0,0 +1,103 @@
+tendopayHelper = $tendopayHelper;
+ }
+
+ /**
+ * @param null $transport
+ * @return \Magento\Framework\DataObject|null
+ * @throws \Magento\Framework\Exception\LocalizedException
+ */
+ protected function _prepareSpecificInformation($transport = null)
+ {
+ if (null !== $this->_paymentSpecificInformation) {
+ return $this->_paymentSpecificInformation;
+ }
+
+ $transport = parent::_prepareSpecificInformation($transport);
+
+ $helper = $this->tendopayHelper;
+
+ if (!$this->getIsSecureMode()) {
+ $info = $this->getInfo();
+ $order = $info->getOrder();
+ $txnId = $info->getLastTransId();
+ if (!$txnId) { // if order doesn't have transaction (for instance: Pending Payment orders)
+ $tendopayOrderId = $order->getData('tendopay_order_id');
+ $tendopayToken = $order->getData('tendopay_token');
+ $tendopayDisposition = $order->getData('tendopay_disposition');
+ $tendopayVerificationToken = $order->getData('tendopay_verification_token');
+ $tendopayFetchedAt = $order->getData('tendopay_fetched_at');
+ $transport->addData(
+ ['Tendopay Order ID' => $tendopayOrderId ? $tendopayOrderId : __('(none)')]
+ );
+ $transport->addData(
+ ['Tendopay Order Token' => $tendopayToken ? $tendopayToken : __('(none)')]
+ );
+ $transport->addData(
+ ['Tendopay Order Status' => $tendopayDisposition ? $tendopayDisposition : __('(none)')]
+ );
+ $transport->addData(
+ ['Tendopay Verification Token' => $tendopayVerificationToken ? $tendopayVerificationToken : __('(none)')]
+ );
+ $transport->addData(
+ ['Tendopay Token Fetched At' => ($tendopayFetchedAt && $tendopayFetchedAt != '0000-00-00 00:00:00') ?
+ $helper->getFormateDate($tendopayFetchedAt, 'M d, Y') :
+ __('(none)')]
+ );
+ } else { // if order already has transaction
+ $transport->addData(['Transaction ID' => $txnId]);
+
+ $additionalInfo = $info->getAdditionalInformation();
+
+ if (is_array($additionalInfo)) {
+ if (isset($additionalInfo['tp_transaction_status'])) {
+ $transport->addData(['Transaction Status' => $additionalInfo['tp_transaction_status']]);
+ }
+ if (isset($additionalInfo['tp_created_at'])) {
+ $transport->addData(['Transaction Created At' => $additionalInfo['tp_created_at']]);
+ }
+ }
+ }
+ }
+
+ return $transport;
+ }
+}
diff --git a/Client/Client.php b/Client/Client.php
new file mode 100755
index 0000000..49b44b5
--- /dev/null
+++ b/Client/Client.php
@@ -0,0 +1,15 @@
+objectManager = $objectManager;
+ $this->config = $config;
+ $this->instanceName = $instanceName;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function create()
+ {
+ $config = [
+ Data::CLIENT_ID_KEY => $this->config->getValue('api_client_id'),
+ Data::CLIENT_SECRET_KEY => $this->config->getValue('api_client_secret'),
+ Data::TENDOPAY_SANDBOX_ENABLED => $this->config->getValue('api_mode')
+ ];
+ return $this->objectManager->create($this->instanceName, ['config' => $config]);
+ }
+}
diff --git a/Client/ClientFactoryInterface.php b/Client/ClientFactoryInterface.php
new file mode 100755
index 0000000..4d13633
--- /dev/null
+++ b/Client/ClientFactoryInterface.php
@@ -0,0 +1,16 @@
+_initService();
+// $this->_service->placeOrder();
+//
+// $quoteId = $this->getQuote()->getId();
+// $this->getCheckoutSession()->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
+//
+// $order = $this->_service->getOrder();
+//
+// if ($order) {
+// $this->getCheckoutSession()->setLastOrderId($order->getId())
+// ->setLastRealOrderId($order->getIncrementId());
+// }
+//
+// $this->_redirect('checkout/onepage/success');
+ }
+}
diff --git a/Controller/Standard/Redirect.php b/Controller/Standard/Redirect.php
index d0856d6..866403c 100644
--- a/Controller/Standard/Redirect.php
+++ b/Controller/Standard/Redirect.php
@@ -12,172 +12,88 @@
namespace TendoPay\TendopayPayment\Controller\Standard;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Quote\Model\Quote;
+use TendoPay\SDK\Exception\TendoPayConnectionException;
+use TendoPay\TendopayPayment\Controller\TendopayAbstract;
+use TendoPay\TendopayPayment\Helper\Data;
+
/**
* Class Redirect
* @package TendoPay\TendopayPayment\Controller\Standard
*/
-class Redirect extends \TendoPay\TendopayPayment\Controller\TendopayAbstract
+class Redirect extends TendopayAbstract
{
- /**
- * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\Result\Json|\Magento\Framework\Controller\ResultInterface
- * @throws \GuzzleHttp\Exception\GuzzleException
- * @throws \Magento\Framework\Exception\LocalizedException
- * @throws \Magento\Framework\Exception\NoSuchEntityException
- */
public function execute()
{
- $this->checkoutHelper->addTendopayLog(
- 'Initiate Redirect Method',
- 'info'
- );
- if (!$this->getRequest()->isAjax()) {
- $this->_cancelPayment();
- $this->checkoutSession->restoreQuote();
- $this->getResponse()->setRedirect(
- $this->getCheckoutHelper()->getUrl('checkout')
- );
- }
-
- $quote = $this->getQuote();
- $email = $this->getRequest()->getParam('email');
- if ($this->getCustomerSession()->isLoggedIn()) {
- $this->getCheckoutSession()->loadCustomerQuote();
- $quote->updateCustomerData($this->getQuote()->getCustomer());
- } else {
- $quote->setCustomerEmail($email);
- }
-
- if ($this->getCustomerSession()->isLoggedIn()) {
- $quote->setCheckoutMethod(\Magento\Checkout\Model\Type\Onepage::METHOD_CUSTOMER);
- } else {
- $quote->setCheckoutMethod(\Magento\Checkout\Model\Type\Onepage::METHOD_GUEST);
- }
-
- $quote->setCustomerEmail($email);
- $quote->save();
-
- $order = $this->getOrder();
- if (!$order->getIncrementId()) {
- $message = 'Payment redirect request: Cannot get order from session, redirecting customer to shopping cart';
- $this->messageManager->addErrorMessage(
- $message
- );
- $this->checkoutHelper->addTendopayLog($message, 'error');
- return $this->_redirect('checkout/cart');
- }
- $this->checkoutHelper->addTendopayLog(
- 'Payment redirect request for order ' . $order->getIncrementId(),
- 'info'
- );
- $this->checkoutHelper->addTendopayLog(
- 'Redirecting customer to TendoPay website... order=' . $order->getIncrementId(),
- 'info'
- );
try {
- $authToken = $this->requestToken($order);
- $this->setDescription($authToken, $order);
- } catch (\Exception $e) {
- throw new \Magento\Framework\Exception\LocalizedException(__("Could not communicate with TendoPay."));
+ $url = $this->getRedirectUrl();
+ if ($url) {
+ $this->getResponse()->setRedirect($url);
+ return;
+ }
+ } catch (LocalizedException $e) {
+ $this->messageManager->addWarningMessage($e->getMessage());
+ } catch (TendoPayConnectionException $e) {
+ $this->messageManager->addWarningMessage($e->getMessage());
}
- $session = $this->checkoutHelper->getCheckoutSession();
- $session->setTendopayStandardQuoteId($session->getQuoteId());
- $params = $this->getPaymentMethod()->buildCheckoutRequest($authToken);
-
- if (empty($params)) {
- $this->checkoutHelper->addTendopayLog(
- 'Exception on processing payment redirect request',
- 'error'
- );
- $this->cancelAction();
- }
- return $this->resultJsonFactory->create()->setData($params);
+ $this->_redirect('checkout/cart');
}
/**
- * Call API to get Authorization Token
+ * Call API to get Authorization Url
*
- * @param $order
+ * @param Quote $quote
* @return string
- * @throws \GuzzleHttp\Exception\GuzzleException
- * @throws \Magento\Framework\Exception\LocalizedException
+ * @throws LocalizedException
+ * @throws TendoPayConnectionException
*/
- public function requestToken($order)
+ public function requestUrl(Quote $quote)
{
- $data = [
- $this->checkoutHelper->getAmountParam() => (int)($order->getGrandTotal()),
- $this->checkoutHelper->getTendopayCustomerReferenceOne() => (string)$order->getIncrementId(),
- $this->checkoutHelper->getTendopayCustomerReferencetwo() => "magento2_order_" . $order->getIncrementId(),
- ];
+ $quote = $quote->collectTotals();
- $response = $this->checkoutHelper->doCall($this->checkoutHelper->getAuthorizationEndpointUri(), $data);
- $isValidResponse = $response->getCode() === 200 && !empty($response->getBody());
-
- if (!$isValidResponse) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('Got return code != 200 or empty body while requesting authorization token from TP')
+ if ($quote->getGrandTotal() < 100) {
+ throw new LocalizedException(
+ __('The minimum purchase amount is ₱100. Please increase your cart total.')
);
}
- return trim((string)$response->getBody(), "\"");
- }
-
- /**
- * Call API to send order details to tendopay
- *
- * @param $authorizationToken
- * @param $order
- * @throws \GuzzleHttp\Exception\GuzzleException
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- public function setDescription($authorizationToken, $order)
- {
- $orderDetails = null;
- try {
- $orderDetails = $this->checkoutHelper->getApiAdapter()->buildOrderTokenRequest($order);
- if (!is_array($orderDetails) && !is_object($orderDetails)) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('Order details parameter must be either ARRAY or OBJECT')
- );
- }
- } catch (\Exception $e) {
- $this->checkoutHelper->addTendopayLog($e->getMessage(), 'warning');
- $orderDetails = new \StdClass;
+ $quote->reserveOrderId();
+ $this->quoteRepository->save($quote);
+ $client = $this->_clientFactory->create();
+
+ $payment = $this->_paymentFactory->create();
+ $payment->setMerchantOrderId($quote->getReservedOrderId())
+ ->setRequestAmount((int)$quote->getGrandTotal())
+ ->setCurrency($quote->getQuoteCurrencyCode())
+ ->setRedirectUrl($this->checkoutHelper->getRedirectUrl());
+ /* Debug */
+ if ($this->_config->getValue('debug')) {
+ $requestData = [
+ Data::PAYMENT_REQUST_PARAM_AMOUNT => $payment->getRequestAmount(),
+ Data::PAYMENT_REQUST_PARAM_MECHANT_ORDER_ID => $payment->getMerchantOrderId(),
+ Data::PAYMENT_REQUST_PARAM_CURRENCY => $payment->getCurrency(),
+ Data::PAYMENT_REQUST_PARAM_REDIRECT => $payment->getRedirectUrl(),
+ Data::PAYMENT_REQUST_PARAM_DESCRIPTION => $payment->getDescription()
+ ];
+ $this->logger->debug(json_encode($requestData));
}
+ /* END Debug */
- $response = $this->checkoutHelper->doCall(
- $this->checkoutHelper->getDescriptionEndpointUri(),
- [
- $this->checkoutHelper->getAuthTokenParam() => $authorizationToken,
- $this->checkoutHelper->getTendopayCustomerReferenceOne() => (string)$order->getIncrementId(),
- $this->checkoutHelper->getTendopayCustomerReferencetwo() => "magento2_order_" .
- $order->getIncrementId(),
- $this->checkoutHelper->getDescParam() => json_encode($orderDetails),
- ]
- );
-
- if ($response->getCode() !== 204) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('Got response code != 204 while sending products description')
- );
- }
+ $client->setPayment($payment);
+ return $client->getAuthorizeLink();
}
/**
- * Cancel Action
- *
- * @throws \Exception
+ * @throws LocalizedException
+ * @throws TendoPayConnectionException
*/
- private function cancelAction()
+ public function getRedirectUrl()
{
- $this->checkoutSession->setQuoteId($this->checkoutSession->getTendopayStandardQuoteId(true));
- if ($this->checkoutSession->getLastRealOrderId()) {
- $order = $this->orderFactory->create()->loadByIncrementId($this->checkoutSession->getLastRealOrderId());
- if ($order->getId()) {
- $order->cancel()->save();
- }
- $this->checkoutHelper->restoreQuote();
- }
- $this->_redirect('checkout/cart');
+ $this->initCheckout();
+ $quote = $this->getQuote();
+
+ return $this->requestUrl($quote);
}
}
diff --git a/Controller/Standard/Success.php b/Controller/Standard/Success.php
index 13601ad..ea55152 100644
--- a/Controller/Standard/Success.php
+++ b/Controller/Standard/Success.php
@@ -12,202 +12,73 @@
namespace TendoPay\TendopayPayment\Controller\Standard;
-use \TendoPay\TendopayPayment\Model\Standard;
-use \TendoPay\TendopayPayment\Helper\Data as tendoPayHelper;
+use Exception;
+use Magento\Framework\App\ResponseInterface;
+use Magento\Framework\Controller\ResultInterface;
+use Magento\Framework\Exception\LocalizedException;
+use TendoPay\SDK\Models\VerifyTransactionRequest;
+use TendoPay\SDK\V2\ConstantsV2;
+use TendoPay\SDK\V2\TendoPayClient;
+use TendoPay\TendopayPayment\Controller\TendopayAbstract;
/**
* Class Success
* @package TendoPay\TendopayPayment\Controller\Standard
*/
-class Success extends \TendoPay\TendopayPayment\Controller\TendopayAbstract
+class Success extends TendopayAbstract
{
/**
- * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
- * @throws \Exception
+ * @return ResponseInterface|ResultInterface
+ * @throws Exception
*/
public function execute()
{
$postedData = $this->getRequest()->getParams();
- if (isset($postedData['action'])) {
- unset($postedData['action']);
- }
-
- $getTendopayCustomerReferenceOne = $this->checkoutHelper->getTendopayCustomerReferenceOne();
- $order = $this->orderFactory->create()->loadByIncrementId($postedData[$getTendopayCustomerReferenceOne]);
- if ($order->getIncrementId()) {
- $orderKey = $postedData[$getTendopayCustomerReferenceOne];
- if ($order->getIncrementId() !== $orderKey) {
- $this->checkoutHelper->addTendopayError("Wrong order key provided");
- } else {
- switch ($order->getStatus()) {
- case tendoPayHelper::RESPONSE_STATUS_APPROVED:
- $this->preVerifyPaymentAction($order, $postedData);
- break;
- case tendoPayHelper::RESPONSE_STATUS_PROCESSING:
- case tendoPayHelper::RESPONSE_STATUS_PENDING:
- $this->preVerifyPaymentAction($order, $postedData);
- break;
- case tendoPayHelper::RESPONSE_STATUS_DECLINED:
- $this->cancelAction();
- $this->paymentMethod->resetTransactionToken();
- $this->checkoutHelper->addTendopayError(
- 'TendoPay payment has been declined. Please use other payment method.'
- );
- break;
- default:
- $this->cancelAction();
- $this->paymentMethod->resetTransactionToken();
- $this->checkoutHelper->addTendopayError(
- 'Cannot find TendoPay payment. Please contact administrator.'
- );
- break;
- }
- $this->tendopaySuccessAction($order);
- }
- }
- $this->_redirect('checkout/onepage/success', ['_secure' => true]);
- }
+ $client = $this->_clientFactory->create();
- /**
- * @throws \Exception
- */
- public function tendopaySuccessAction($order)
- {
- $this->checkoutSession->clearHelperData();
- $quoteId = $this->checkoutSession->getQuote()->getId();
- $this->checkoutSession->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
- if ($order) {
- $this->checkoutSession->setLastOrderId($order->getId())
- ->setLastRealOrderId($order->getIncrementId())
- ->setLastOrderStatus($order->getStatus());
- }
- $this->_redirect('checkout/onepage/success', ['_secure' => true]);
- }
-
- /**
- * @param $order
- * @param $postedData
- */
- public function preVerifyPaymentAction($order, $postedData)
- {
- $this->performVerification($order, $postedData);
- }
-
- /**
- * @param $order
- * @param $postedData
- * @return bool
- * @throws \GuzzleHttp\Exception\GuzzleException
- */
- public function performVerification($order, $postedData)
- {
- $tendoPayMerchantId = $postedData[$this->checkoutHelper->getVendorIdParam()];
- $localTendoPayMerchantId = $this->checkoutHelper->getConfigValues(
- $this->checkoutHelper->getAPIMerchantIDConfigField()
- );
+ if (TendoPayClient::isCallbackRequest($postedData)) {
+ $transaction = $client->verifyTransaction(new VerifyTransactionRequest($postedData));
- if ($tendoPayMerchantId !== $localTendoPayMerchantId) {
- $this->checkoutHelper->addTendopayError("Malformed payload");
- }
-
- try {
- $transactionVerified = $this->verifyPayment($order, $postedData);
- } catch (\Exception $exception) {
- $this->checkoutHelper->addTendopayError("Could not communicate with TendoPay properly");
- }
+ if (!$transaction->isVerified()) {
+ throw new LocalizedException(__('Invalid signature for the verification'));
+ }
- if ($transactionVerified) {
- return true;
- } else {
- $order->sendNewOrderEmail()->addStatusHistoryComment(
- 'Could not get with TendoPay transaction verification properly'
- )
- ->setIsCustomerNotified(false)
- ->save();
- $this->_forward('error');
- $this->_redirect('checkout/cart');
+ if ($transaction->getStatus() == ConstantsV2::STATUS_SUCCESS) {
+ $this->_initService();
+ $this->_service->prepareCallbackData($transaction);
+ $this->_success();
+ $this->_redirect('checkout/onepage/success');
+ } elseif ($transaction->getStatus() == ConstantsV2::STATUS_FAILURE) {
+ $this->messageManager->addWarningMessage(__($transaction->getMessage()));
+
+ $resultRedirect = $this->resultRedirectFactory->create();
+ return $resultRedirect->setPath('checkout/cart');
+ } elseif ($transaction->getStatus() === ConstantsV2::STATUS_CANCELED) {
+ if ($this->_config->getValue('debug')) {
+ $this->logger->debug(json_encode($transaction->toArray()));
+
+ $resultRedirect = $this->resultRedirectFactory->create();
+ return $resultRedirect->setPath('checkout/cart');
+ }
+ }
}
}
- /**
- * Call API to verify Payment
- *
- * @param $order
- * @param array $data
- * @return bool
- * @throws \GuzzleHttp\Exception\GuzzleException
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- public function verifyPayment($order, array $data)
+ protected function _success()
{
- ksort($data);
- $hash = $data[$this->checkoutHelper->getHashParam()];
- if ($hash !== $this->checkoutHelper->calculate($data)) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __("Hash doesn't match", "tendopay")
- );
- }
- $disposition = $data[$this->checkoutHelper->getDispositionParam()];
- $tendoPayTransactionNumber = $data[$this->checkoutHelper->getTransactionNoParam()];
- $verificationToken = $data[$this->checkoutHelper->getVerificationTokenParam()];
- $tendoPayUserId = $data[$this->checkoutHelper->getUserIDParam()];
+ $this->_initService();
+ $this->_service->placeOrder();
- $verificationData = [
- $this->checkoutHelper->getTendopayCustomerReferenceOne() => (string)$order->getIncrementId(),
- $this->checkoutHelper->getTendopayCustomerReferencetwo() => "magento2_order_" . $order->getIncrementId(),
- $this->checkoutHelper->getDispositionParam() => $disposition,
- $this->checkoutHelper->getVendorIdParam() => (string)$this->checkoutHelper->getConfigValues(
- $this->checkoutHelper->getAPIMerchantIDConfigField()
- ),
- $this->checkoutHelper->getTransactionNoParam() => (string)$tendoPayTransactionNumber,
- $this->checkoutHelper->getVerificationTokenParam() => $verificationToken,
- $this->checkoutHelper->getUserIDParam() => $tendoPayUserId,
- ];
+ $quoteId = $this->getQuote()->getId();
+ $this->getCheckoutSession()->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
- $response = $this->checkoutHelper->doCall(
- $this->checkoutHelper->getVerificationEndpointUri(),
- $verificationData
- );
+ $order = $this->_service->getOrder();
- if ($response->getCode() !== 200) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('Received error: %1 while trying to verify the transaction', $response->getCode())
- );
+ if ($order) {
+ $this->getCheckoutSession()->setLastOrderId($order->getId())
+ ->setLastRealOrderId($order->getIncrementId());
}
-
- $json = json_decode($response->getBody());
-
- $session = $this->checkoutHelper->getCheckoutSession();
- $quote = $session->getQuote();
- $quote->setData('tendopay_order_id', $order->getTendopayOrderId())->save();
- $quote->setData('tendopay_token', $order->getTendopayToken())->save();
-
- $order->setData('tendopay_token', $json->tendopay_hash);
- $order->setData('tendopay_order_id', $json->tendopay_transaction_number);
- $order->setData('tendopay_disposition', $this->getRequest()->getParam('tendopay_disposition'));
- $order->setData('tendopay_verification_token', $this->getRequest()->getParam('tendopay_verification_token'));
- $order->setData('tendopay_fetched_at', $this->checkoutHelper->getGmtDate());
- $order->save();
-
- return $json->{$this->checkoutHelper->getStatusIDParam()} === 'success';
}
- /**
- * Cancel Action
- *
- * @throws \Exception
- */
- public function cancelAction()
- {
- $this->checkoutSession->setQuoteId($this->checkoutSession->getTendopayStandardQuoteId(true));
- if ($this->checkoutSession->getLastRealOrderId()) {
- $order = $this->orderFactory->create()->loadByIncrementId($this->checkoutSession->getLastRealOrderId());
- if ($order->getId()) {
- $order->cancel()->save();
- }
- $this->checkoutHelper->restoreQuote();
- }
- $this->_redirect('checkout/cart');
- }
}
diff --git a/Controller/TendopayAbstract.php b/Controller/TendopayAbstract.php
index f3838f4..e5c88b7 100644
--- a/Controller/TendopayAbstract.php
+++ b/Controller/TendopayAbstract.php
@@ -13,8 +13,9 @@
namespace TendoPay\TendopayPayment\Controller;
use Magento\Framework\App\Action\Context;
+use TendoPay\TendopayPayment\Client\ClientFactoryInterface;
-class TendopayAbstract extends \Magento\Framework\App\Action\Action
+abstract class TendopayAbstract extends \Magento\Framework\App\Action\Action
{
/**
* @var \Magento\Checkout\Model\Session
@@ -46,11 +47,6 @@ class TendopayAbstract extends \Magento\Framework\App\Action\Action
*/
protected $quote;
- /**
- * @var \TendoPay\TendopayPayment\Model\Standard
- */
- protected $paymentMethod;
-
/**
* @var \TendoPay\TendopayPayment\Helper\Data
*/
@@ -65,6 +61,30 @@ class TendopayAbstract extends \Magento\Framework\App\Action\Action
* @var \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
*/
protected $resultJsonFactory;
+ /**
+ * @var \TendoPay\TendopayPayment\Model\Service\TendoFactory
+ */
+ private $_tendoService;
+ /**
+ * @var \TendoPay\TendopayPayment\Model\Service\Tendo
+ */
+ protected $_service;
+ /**
+ * @var Context
+ */
+ private $context;
+ /**
+ * @var ClientFactoryInterface
+ */
+ protected $_clientFactory;
+ /**
+ * @var \TendoPay\TendopayPayment\Client\Model\PaymentFactory
+ */
+ protected $_paymentFactory;
+ /**
+ * @var \Magento\Payment\Gateway\ConfigInterface
+ */
+ protected $_config;
public function __construct(
Context $context,
@@ -73,21 +93,29 @@ public function __construct(
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Psr\Log\LoggerInterface $logger,
- \TendoPay\TendopayPayment\Model\Standard $paymentMethod,
\TendoPay\TendopayPayment\Helper\Data $checkoutHelper,
\Magento\Quote\Api\CartManagementInterface $cartManagement,
- \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
+ \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
+
+ \Magento\Payment\Gateway\ConfigInterface $config,
+ \TendoPay\TendopayPayment\Model\Service\TendoFactory $tendoService,
+ ClientFactoryInterface $clientFactory,
+ \TendoPay\TendopayPayment\Client\Model\PaymentFactory $paymentFactory
) {
parent::__construct($context);
$this->customerSession = $customerSession;
$this->checkoutSession = $checkoutSession;
$this->quoteRepository = $quoteRepository;
$this->orderFactory = $orderFactory;
- $this->paymentMethod = $paymentMethod;
$this->checkoutHelper = $checkoutHelper;
$this->cartManagement = $cartManagement;
$this->resultJsonFactory = $resultJsonFactory;
$this->logger = $logger;
+ $this->_tendoService = $tendoService;
+ $this->context = $context;
+ $this->_clientFactory = $clientFactory;
+ $this->_paymentFactory = $paymentFactory;
+ $this->_config = $config;
}
/**
@@ -173,14 +201,6 @@ public function getCustomerSession()
return $this->customerSession;
}
- /**
- * @return \TendoPay\TendopayPayment\Model\Standard
- */
- public function getPaymentMethod()
- {
- return $this->paymentMethod;
- }
-
/**
* @return \TendoPay\TendopayPayment\Helper\Data
*/
@@ -189,7 +209,18 @@ protected function getCheckoutHelper()
return $this->checkoutHelper;
}
- public function execute()
+ protected function _initService()
{
+ $quote = $this->getQuote();
+
+ if (!$this->_service) {
+ $parameters = [
+ 'params' => [
+ 'quote' => $quote,
+// 'config' => $this->_config,
+ ],
+ ];
+ $this->_service = $this->_tendoService->create($parameters);
+ }
}
}
diff --git a/Gateway/Http/Client/AbstractClient.php b/Gateway/Http/Client/AbstractClient.php
new file mode 100755
index 0000000..f3b5111
--- /dev/null
+++ b/Gateway/Http/Client/AbstractClient.php
@@ -0,0 +1,71 @@
+logger = $logger;
+ $this->_clientFactory = $clientFactory;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function placeRequest(TransferInterface $transferObject)
+ {
+
+ $data = $transferObject->getBody();
+
+ $log = [
+ 'request' => $transferObject->getBody(),
+ 'client' => static::class
+ ];
+
+ $response = [];
+
+ try {
+ $response = $this->process($data);
+ } catch (\Exception $e) {
+ $message = $e->getMessage() ? $e->getMessage() : "Something went wrong during Gateway request.";
+ $log['error'] = $message;
+ $this->logger->debug($log);
+ }
+
+ return $response;
+ }
+
+ /**
+ * Process http request
+ *
+ * @param array $data
+ */
+ abstract protected function process(array $data);
+}
diff --git a/Gateway/Http/Client/CaptureClient.php b/Gateway/Http/Client/CaptureClient.php
new file mode 100755
index 0000000..a9a0b9d
--- /dev/null
+++ b/Gateway/Http/Client/CaptureClient.php
@@ -0,0 +1,25 @@
+_clientFactory->create();
+ $response = $client->getTransactionDetail($data[Data::PAYMENT_INFO_TP_TRANSACTION_ID]);
+ $response = $response->toArray();
+ return $response;
+ }
+}
diff --git a/Gateway/Http/TransferFactory.php b/Gateway/Http/TransferFactory.php
new file mode 100755
index 0000000..73af408
--- /dev/null
+++ b/Gateway/Http/TransferFactory.php
@@ -0,0 +1,37 @@
+transferBuilder = $transferBuilder;
+ }
+
+ /**
+ * Builds gateway transfer object
+ *
+ * @param array $request
+ * @return TransferInterface
+ */
+ public function create(array $request)
+ {
+ return $this->transferBuilder
+ ->setBody($request)
+ ->build();
+ }
+}
diff --git a/Gateway/Request/AuthorizationRequestBuilder.php b/Gateway/Request/AuthorizationRequestBuilder.php
new file mode 100755
index 0000000..b90962a
--- /dev/null
+++ b/Gateway/Request/AuthorizationRequestBuilder.php
@@ -0,0 +1,54 @@
+subjectReader = $subjectReader;
+ $this->config = $config;
+ }
+
+ /**
+ * Builds ENV request
+ *
+ * @param array $buildSubject
+ * @return array
+ */
+ public function build(array $buildSubject)
+ {
+ $data = [];
+
+ $paymentDO = $this->subjectReader->readPayment($buildSubject);
+ $payment = $paymentDO->getPayment();
+
+ $data[Data::PAYMENT_INFO_TP_TRANSACTION_ID] = $payment->getAdditionalInformation(Data::PAYMENT_INFO_TP_TRANSACTION_ID);
+
+ return $data;
+ }
+}
diff --git a/Gateway/Response/CompleteSaleHandler.php b/Gateway/Response/CompleteSaleHandler.php
new file mode 100755
index 0000000..dde4579
--- /dev/null
+++ b/Gateway/Response/CompleteSaleHandler.php
@@ -0,0 +1,65 @@
+logger = $logger;
+ $this->subjectReader = $subjectReader;
+ }
+
+ /**
+ * @param array $handlingSubject
+ * @param array $response
+ * @throws \Exception
+ */
+ public function handle(array $handlingSubject, array $response)
+ {
+ /**
+ * $payment \Magento\Sales\Model\Order\Payment
+ */
+
+ $paymentDO = $this->subjectReader->readPayment($handlingSubject);
+ $payment = $paymentDO->getPayment();
+
+ if ($response[Data::TRANSACTION_INFO_STATUS]) {
+ $payment->setTransactionId($response[Data::TRANSACTION_INFO_ID]);
+ $payment->setAdditionalInformation(Data::TRANSACTION_INFO_STATUS, $response[Data::TRANSACTION_INFO_STATUS]);
+ $payment->setAdditionalInformation(Data::TRANSACTION_INFO_CREATED_AT, $response[Data::TRANSACTION_INFO_CREATED_AT]);
+ $payment->setIsTransactionClosed(true);
+
+ if ($response[Data::TRANSACTION_INFO_STATUS] === Data::TRANSACTION_STATUS_PAID) {
+ $payment->setIsTransactionApproved(true);
+ } elseif ($response[Data::TRANSACTION_INFO_STATUS] === Data::TRANSACTION_STATUS_CANCELED) {
+ $payment->setIsTransactionDenied(true);
+ $order = $payment->getOrder();
+ $order->setState($order::STATE_CANCELED)->setStatus($order::STATE_CANCELED);
+ }
+ }
+ }
+}
diff --git a/Gateway/Validator/CurrencyValidator.php b/Gateway/Validator/CurrencyValidator.php
new file mode 100755
index 0000000..a869811
--- /dev/null
+++ b/Gateway/Validator/CurrencyValidator.php
@@ -0,0 +1,67 @@
+config = $config;
+ parent::__construct($resultFactory);
+ $this->_storeManager = $storeManager;
+ }
+
+ /**
+ * @param array $validationSubject
+ * @return ResultInterface
+ * @throws NoSuchEntityException
+ */
+ public function validate(array $validationSubject)
+ {
+ $allowedCurrency = $this->config->getValue('currency');
+ $currentCurrency = $this->_storeManager->getStore()->getCurrentCurrency()->getCode();
+
+ if ($allowedCurrency == $currentCurrency) {
+ return $this->createResult(
+ true,
+ ['status' => 200]
+ );
+ }
+
+ return $this->createResult(
+ false,
+ [__('The currency selected is not supported by Tendo Pay.')]
+ );
+ }
+}
diff --git a/Helper/Data.php b/Helper/Data.php
index c71f6da..0ebb298 100644
--- a/Helper/Data.php
+++ b/Helper/Data.php
@@ -12,9 +12,9 @@
namespace TendoPay\TendopayPayment\Helper;
+use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
-use Magento\Framework\App\Config\ScopeConfigInterface;
/**
* Class Data
@@ -22,6 +22,28 @@
*/
class Data extends AbstractHelper
{
+ const CLIENT_ID_KEY = 'CLIENT_ID';
+ const CLIENT_SECRET_KEY = 'CLIENT_SECRET';
+ const REDIRECT_URL_KEY = 'REDIRECT_URL';
+ const TENDOPAY_SANDBOX_ENABLED = 'TENDOPAY_SANDBOX_ENABLED';
+
+ const PAYMENT_INFO_TP_TRANSACTION_ID = 'tp_transaction_id';
+
+ const TRANSACTION_INFO_STATUS = 'tp_transaction_status';
+ const TRANSACTION_INFO_ID = 'tp_transaction_id';
+ const TRANSACTION_INFO_CREATED_AT = 'tp_created_at';
+
+ const TRANSACTION_STATUS_PAID = 'PAID';
+ const TRANSACTION_STATUS_CANCELED = 'CANCELED';
+
+ const PAYMENT_REQUST_PARAM_AMOUNT = 'tp_amount';
+ const PAYMENT_REQUST_PARAM_CURRENCY = 'tp_currency';
+ const PAYMENT_REQUST_PARAM_MECHANT_ORDER_ID = 'tp_merchant_order_id';
+ const PAYMENT_REQUST_PARAM_DESCRIPTION = 'tp_description';
+ const PAYMENT_REQUST_PARAM_REDIRECT = 'tp_redirect_url';
+
+
+
const PAYMANET_FAILED_QUERY_PARAM = 'tendopay_payment_failed';
const METHOD_WPS = 'tendopay';
const REDIRECT_URL_PATTERN = '^tendopay-result/?';
@@ -34,8 +56,9 @@ class Data extends AbstractHelper
const REDIRECT_URI = 'https://app.tendopay.ph/payments/authorise';
const VIEW_URI_PATTERN = 'https://app.tendopay.ph/view/transaction/%s';
const VERIFICATION_ENDPOINT_URI = 'payments/api/v1/verification';
- const AUTHORIZATION_ENDPOINT_URI = 'payments/api/v1/authTokenRequest';
const DESCRIPTION_ENDPOINT_URI = 'payments/api/v1/paymentDescription';
+
+ const AUTHORIZATION_ENDPOINT_URI = 'payments/api/v2/order';
const BEARER_TOKEN_ENDPOINT_URI = 'oauth/token';
/**
@@ -52,14 +75,14 @@ class Data extends AbstractHelper
/**
* Below constant names are used as keys of data send to or received from TP API
*/
- const AMOUNT_PARAM = 'tendopay_amount';
+
const AUTH_TOKEN_PARAM = 'tendopay_authorisation_token';
const TENDOPAY_CUSTOMER_REFERENCE_1 = 'tendopay_customer_reference_1';
const TENDOPAY_CUSTOMER_REFERENCE_2 = 'tendopay_customer_reference_2';
- const REDIRECT_URL_PARAM = 'tendopay_redirect_url';
const VENDOR_ID_PARAM = 'tendopay_tendo_pay_vendor_id';
const VENDOR_PARAM = 'tendopay_vendor';
- const HASH_PARAM = 'tendopay_hash';
+// const HASH_PARAM = 'tendopay_hash';
+
const DISPOSITION_PARAM = 'tendopay_disposition';
const TRANSACTION_NO_PARAM = 'tendopay_transaction_number';
const VERIFICATION_TOKEN_PARAM = 'tendopay_verification_token';
@@ -67,6 +90,12 @@ class Data extends AbstractHelper
const STATUS_PARAM = 'tendopay_status';
const USER_ID_PARAM = 'tendopay_user_id';
+ const CURRENCY_PARAM = 'tp_currency';
+ const MERCHANT_ORDER_ID_PARAM = 'tp_merchant_order_id';
+ const REDIRECT_URL_PARAM = 'tp_redirect_url';
+ const AMOUNT_PARAM = 'tp_amount';
+ const HASH_PARAM = 'x_signature';
+
const TENDO_PAY_FAQ_URL = 'https://tendopay.ph/page-faq.html';
/**
@@ -138,7 +167,12 @@ class Data extends AbstractHelper
* @var string $bearerToken the bearer token requested in previous API calls. If it's null, it will be taken from
* wordpress options. If it was null or expired in the options, it will be then requested from the API.
*/
- private static $_bearerToken;
+ private $_bearerToken;
+
+ /**
+ * @var int
+ */
+ private $_bearerTokenExpirationTimestamp;
/**
* @var string
@@ -313,7 +347,7 @@ public function getVerificationEndpointUri()
*/
public function getAuthorizationEndpointUri()
{
- return $this->isSandboxEnabled() ? self::SANDBOX_AUTHORIZATION_ENDPOINT_URI : self::AUTHORIZATION_ENDPOINT_URI;
+ return self::AUTHORIZATION_ENDPOINT_URI;
}
/**
@@ -333,7 +367,7 @@ public function getDescriptionEndpointUri()
*/
public function getBearerTokenEndpointUri()
{
- return $this->isSandboxEnabled() ? self::SANDBOX_BEARER_TOKEN_ENDPOINT_URI : self::BEARER_TOKEN_ENDPOINT_URI;
+ return self::BEARER_TOKEN_ENDPOINT_URI;
}
/**
@@ -346,6 +380,7 @@ public function getRepaymentCalculatorApiEndpointUrl()
$baseUrl = $this->isSandboxEnabled() ? self::SANDBOX_BASE_API_URL : self::BASE_API_URL;
return $baseUrl . "/" . self::REPAYMENT_SCHEDULE_API_ENDPOINT_URI;
}
+
/**
*
* @return bool true if sandbox is enabled
@@ -464,6 +499,19 @@ public function getAmountParam()
return self::AMOUNT_PARAM;
}
+ /**
+ * @return string
+ */
+ public function getCurrencyParam()
+ {
+ return self::CURRENCY_PARAM;
+ }
+
+ public function getMerchantOrderIdParam()
+ {
+ return self::MERCHANT_ORDER_ID_PARAM;
+ }
+
/**
* @return string
*/
@@ -642,6 +690,7 @@ public static function getTendoExampleInstallmentsEnabled()
{
return self::OPTION_TENDOPAY_EXAMPLE_INSTALLMENTS_ENABLE;
}
+
/**
* @return string
*/
@@ -728,23 +777,30 @@ public function versionCompare($ver)
* @param array $data
* @return string
*/
- public function calculate(array $data)
+ public function calculate(array $payload)
{
- $secret = $this->getConfigValues(self::getAPIMerchantSecretConfigField());
- $data = array_map(
- function ($value) {
- return trim($value);
- },
- $data
- );
+ $client_secret = $this->getConfigValues(self::getAPIMerchantSecretConfigField());
+// $data = array_map(
+// function ($value) {
+// return trim($value);
+// },
+// $data
+// );
+
+// $hashKeysExclusionList = [$this->getHashParam()];
+// $exclusionList = $hashKeysExclusionList;
+// $data = $this->arrayFilterKeys($data, $exclusionList);
+
+ ksort($payload);
- $hashKeysExclusionList = [$this->getHashParam()];
- $exclusionList = $hashKeysExclusionList;
- $data = $this->arrayFilterKeys($data, $exclusionList);
+ $message = array_reduce(array_keys($payload), static function ($p, $k) use ($payload) {
+ return strpos($k, 'tp_') === 0 ? $p . $k . trim($payload[$k]) : $p;
+ }, '');
+ $hash = hash_hmac('sha256', $message, $client_secret);
- ksort($data);
- $message = join("", $data);
- return hash_hmac($this->getHashAlgorithm(), $message, $secret, false);
+ return $hash;
+// $message = join("", $data);
+// return hash_hmac($this->getHashAlgorithm(), $message, $secret, false);
}
/**
@@ -756,10 +812,10 @@ function ($value) {
*/
public function arrayFilterKeys($array, $exclusionList)
{
- $newArray= [];
+ $newArray = [];
foreach ($array as $key => $value) {
if (!in_array($key, $exclusionList) && !empty($value)) {
- $newArray[$key]=$value;
+ $newArray[$key] = $value;
}
}
return $newArray;
@@ -775,18 +831,20 @@ public function arrayFilterKeys($array, $exclusionList)
*/
public function doCall($url, array $data)
{
- $merchantId = $this->getConfigValues(self::getAPIMerchantIDConfigField());
- $data[$this->getVendorIdParam()] = $merchantId;
- $data[$this->getHashParam()] = $this->calculate($data);
+
+// $merchantId = $this->getConfigValues(self::getAPIMerchantIDConfigField());
+// $data[$this->getVendorIdParam()] = $merchantId;
+// $data[$this->getHashParam()] = $this->calculate($data);
+ $data['x_signature'] = $this->calculate($data);
$headers = [
'headers' => [
'Authorization' => 'Bearer ' . $this->getBearerToken(),
'Accept' => 'application/json',
'Content-Type' => 'application/json',
- 'X-Using' => 'TendoPay Magento2 Extension',
+// 'X-Using' => 'TendoPay Magento2 Extension',
],
- 'json' => $data
+ 'body' => json_encode($data)
];
$this->client = new \GuzzleHttp\Client(
[
@@ -805,19 +863,19 @@ public function doCall($url, array $data)
*/
private function getBearerToken()
{
-
- if (self::$_bearerToken === null) {
- $bearerTokenConfigField = $this->getConfigValues(self::getBearerTokenConfigField());
- self::$_bearerToken = $bearerTokenConfigField;
+ if ($this->_bearerToken === null) {
+ $bearerTokenConfigField = json_decode($this->getConfigValues(self::getBearerTokenConfigField()), true);
+ $this->_bearerToken = $bearerTokenConfigField['token'];
+ $this->_bearerTokenExpirationTimestamp = $bearerTokenConfigField['expiration_timestamp'];
}
$bearerExpirationTimestamp = -1;
- if (self::$_bearerToken !== null && property_exists(self::$_bearerToken, 'expiration_timestamp')) {
- $bearerExpirationTimestamp = self::$_bearerToken->expiration_timestamp;
+ if ($this->_bearerTokenExpirationTimestamp !== null) {
+ $bearerExpirationTimestamp = $this->_bearerTokenExpirationTimestamp;
}
$currentTimestamp = $this->dateTime->gmtTimestamp();
- if ($bearerExpirationTimestamp <= $currentTimestamp - 30) {
+ if ($bearerExpirationTimestamp <= $currentTimestamp - 60) {
$headers = [
'headers' => [
'Accept' => 'application/json',
@@ -840,28 +898,32 @@ private function getBearerToken()
$responseBody = (string)$response->getBody();
$responseBody = json_decode($responseBody);
- self::$_bearerToken = new \stdClass();
- self::$_bearerToken->expiration_timestamp = $responseBody->expires_in + $currentTimestamp;
- self::$_bearerToken->token = $responseBody->access_token;
+ $bearerToken = [
+ 'expiration_timestamp' => $responseBody->expires_in + $currentTimestamp,
+ 'token' => $responseBody->access_token
+ ];
+
+ $this->_bearerToken = $bearerToken['token'];
+ $this->_bearerTokenExpirationTimestamp = $bearerToken['expiration_timestamp'];
$this->configWriter->save(
'payment/tendopay/bearer_token',
- $this->serializer->serialize(self::$_bearerToken),
+ json_encode($bearerToken),
$scope = ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
$scopeId = 0
);
}
- return self::$_bearerToken->token;
+ return $this->_bearerToken;
}
public function getDefaultHeaders()
{
return [
'Authorization' => 'Bearer ' . $this->getBearerToken(),
- 'Accept' => 'application/json',
- 'Content-Type' => 'application/json',
- 'X-Using' => 'TendoPay Magento2 Plugin',
+ 'Accept' => 'application/json',
+ 'Content-Type' => 'application/json',
+ 'X-Using' => 'TendoPay Magento2 Plugin',
];
}
}
diff --git a/Model/Api/Adapters/Adapterv1.php b/Model/Api/Adapters/Adapterv1.php
index 30491d0..72ba56f 100644
--- a/Model/Api/Adapters/Adapterv1.php
+++ b/Model/Api/Adapters/Adapterv1.php
@@ -97,8 +97,8 @@ public function buildOrderTokenRequest($object)
'subtotal' => $object->getSubtotal(),
'total' => round((float)$object->getGrandTotal(), $precision)
];
- if (!empty($object) && $object->getReservedOrderId()) {
- $params['merchantReference'] = (string)$object->getReservedOrderId();
+ if (!empty($object) && $object->getId()) {
+ $params['merchantReference'] = (string)$object->getId();
}
return $params;
diff --git a/Model/ConfigProvider.php b/Model/ConfigProvider.php
index 6f87a8d..d40910f 100644
--- a/Model/ConfigProvider.php
+++ b/Model/ConfigProvider.php
@@ -12,25 +12,20 @@
namespace TendoPay\TendopayPayment\Model;
-use \TendoPay\TendopayPayment\Helper\Data as TendoPayHelper;
-use Magento\Framework\View\Asset\Repository as AssetRepository;
+use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Framework\App\RequestInterface;
+use Magento\Framework\UrlInterface;
+use Magento\Framework\View\Asset\Repository as AssetRepository;
+use Magento\Payment\Gateway\ConfigInterface;
+use TendoPay\TendopayPayment\Helper\Data as TendoPayHelper;
/**
* Class ConfigProvider
* @package TendoPay\TendopayPayment\Model
*/
-class ConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface
+class ConfigProvider implements ConfigProviderInterface
{
- /**
- * @var string
- */
- protected $methodCode = TendoPayHelper::METHOD_WPS;
-
- /**
- * @var \Magento\Payment\Model\MethodInterface
- */
- protected $method;
+ const CODE = 'tendopay';
/**
* @var AssetRepository
@@ -43,31 +38,31 @@ class ConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface
protected $request;
/**
- * @var Standard
+ * @var UrlInterface
*/
- protected $tendopay;
-
public $url;
+ /**
+ * @var ConfigInterface
+ */
+ private $config;
+
/**
* ConfigProvider constructor.
- * @param \Magento\Payment\Helper\Data $paymenthelper
* @param AssetRepository $assetRepository
+ * @param UrlInterface $url
+ * @param ConfigInterface $config
* @param RequestInterface $request
- * @param Standard $tendopay
- * @throws \Magento\Framework\Exception\LocalizedException
*/
public function __construct(
- \Magento\Payment\Helper\Data $paymenthelper,
AssetRepository $assetRepository,
- RequestInterface $request,
- \TendoPay\TendopayPayment\Model\Standard $tendopay,
- \Magento\Framework\UrlInterface $url
+ UrlInterface $url,
+ ConfigInterface $config,
+ RequestInterface $request
) {
- $this->method = $paymenthelper->getMethodInstance($this->methodCode);
$this->assetRepository = $assetRepository;
- $this->request = $request;
- $this->tendopay = $tendopay;
$this->url = $url;
+ $this->config = $config;
+ $this->request = $request;
}
/**
@@ -77,28 +72,27 @@ public function getConfig()
{
$params = ['_secure' => $this->request->isSecure()];
$visibility = false;
- if (!empty($this->tendopay->getConfigData('api_merchant_id')) &&
- !empty($this->tendopay->getConfigData('api_merchant_secret')) &&
- !empty($this->tendopay->getConfigData('api_client_id')) &&
- !empty($this->tendopay->getConfigData('api_client_secret'))
+ if (!empty($this->config->getValue('api_client_id')) &&
+ !empty($this->config->getValue('api_client_secret'))
) {
$visibility = true;
}
- return $this->method->isAvailable() ? [
- 'payment'=>[
- 'tendopay'=> [
+ return $this->config->getValue('active') ? [
+ 'payment' => [
+ 'tendopay' => [
'visibility' => $visibility,
- 'redirectUrl' => $this->tendopay->getRedirectUrl(),
+ 'redirectUrl' => $this->url->getUrl($this->config->getValue('redirect_url'), $params),
'paymentAcceptanceMarkSrc' => $this->assetRepository->getUrlWithParams(
'TendoPay_TendopayPayment::images/tendopay.png',
$params
),
'paymentAcceptanceMarkHref' => TendoPayHelper::TENDO_PAY_FAQ_URL,
- 'paymentAcceptanceMarkMessage' => $this->tendopay->getConfigData('message'),
- 'tendopayMarketingPopup' => $this->url->getUrl('tendopay/standard/popupbox')
+ 'paymentAcceptanceMarkMessage' => $this->config->getValue('message'),
+ 'tendopayMarketingPopup' => $this->url->getUrl('tendopay/standard/popupbox'),
+ 'minTotalAmount' => $this->config->getValue('min_total_amount'),
]
]
- ]:[];
+ ] : [];
}
}
diff --git a/Model/Service/Tendo.php b/Model/Service/Tendo.php
new file mode 100755
index 0000000..f439650
--- /dev/null
+++ b/Model/Service/Tendo.php
@@ -0,0 +1,130 @@
+_quote = $params['quote'];
+ } else {
+ // phpcs:ignore Magento2.Exceptions.DirectThrow
+ throw new Exception('Quote instance is required.');
+ }
+ $this->_customerSession = $customerSession;
+ $this->_checkoutData = $checkoutData;
+ $this->_quoteManagement = $quoteManagement;
+ $this->quoteRepository = $quoteRepository;
+ }
+
+ public function placeOrder()
+ {
+ if ($this->getCheckoutMethod() == Onepage::METHOD_GUEST) {
+ $this->prepareGuestQuote();
+ }
+
+ $this->_quote->collectTotals();
+ $order = $this->_quoteManagement->submit($this->_quote);
+
+ if (!$order) {
+ return;
+ }
+
+ $this->_order = $order;
+ }
+
+ protected function getCheckoutMethod()
+ {
+ if ($this->getCustomerSession()->isLoggedIn()) {
+ return Onepage::METHOD_CUSTOMER;
+ }
+ if (!$this->_quote->getCheckoutMethod()) {
+ if ($this->_checkoutData->isAllowedGuestCheckout($this->_quote)) {
+ $this->_quote->setCheckoutMethod(Onepage::METHOD_GUEST);
+ } else {
+ $this->_quote->setCheckoutMethod(Onepage::METHOD_REGISTER);
+ }
+ }
+ return $this->_quote->getCheckoutMethod();
+ }
+
+ /**
+ * @return Session
+ */
+ public function getCustomerSession()
+ {
+ return $this->_customerSession;
+ }
+
+ /**
+ * Prepare quote for guest checkout order submit
+ *
+ * @return $this
+ */
+ protected function prepareGuestQuote()
+ {
+ $quote = $this->_quote;
+ $quote->setCustomerId(null)
+ ->setCustomerEmail($quote->getBillingAddress()->getEmail())
+ ->setCustomerIsGuest(true)
+ ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID);
+ return $this;
+ }
+
+ public function getOrder()
+ {
+ return $this->_order;
+ }
+
+ /**
+ * @param VerifyTransactionResponse $data
+ * @throws LocalizedException
+ */
+ public function prepareCallbackData(VerifyTransactionResponse $data)
+ {
+ $quote = $this->_quote;
+ $payment = $quote->getPayment();
+ $payment->setAdditionalInformation(Data::PAYMENT_INFO_TP_TRANSACTION_ID, $data->getTransactionNumber());
+ $quote->collectTotals();
+ $this->quoteRepository->save($quote);
+ }
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2e194a2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+**Step 1: Add TendoPaySDK**
+
+Run the command in terminal on a project
+
+composer require tendopay/tendopay-sdk-php
+
+Copy files of the module into /app/code/
+
+**Step 2: Enable magento 2 extension in terminal**
+
+php bin/magento setup:upgrade
+
+php bin/magento setup:di:compile
+
diff --git a/composer.json b/composer.json
old mode 100644
new mode 100755
index 226c735..3d0e396
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
"name": "tendopay/tendopay-payment",
"description": "TendoPay works as a payment method and allows users to spread their purchase across multiple instalments. User instalment payments are clearly visible with no hidden or additional fees. Application to TendoPay is quick, a user can get approved within 24 hours. Also users can manage their account from anywhere - desktop, mobile or tablet through the TendoPay admin panel. TendoPay was built to help provide users a more flexible payment method suited for timing that works for them",
"type": "magento2-module",
- "version": "1.0.2",
+ "version": "1.1.0",
"license": [
"GNU"
],
@@ -14,10 +14,11 @@
}
],
"require": {
- "php": "~5.6.5|7.*",
+ "php": "~7.1.3||~7.2||~7.3||~7.4",
"magento/framework": ">=100",
"magento/module-backend": ">=100.0.0",
- "magento/module-store": ">=100.0.0"
+ "magento/module-store": ">=100.0.0",
+ "tendopay/tendopay-sdk-php": "~0.9.1"
},
"keywords": [
"magento 2",
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 5ae8874..09f7818 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -16,45 +16,38 @@
-
+
Magento\Config\Model\Config\Source\Yesno
-
+
1
-
-
-
- 1
-
-
-
-
- required-entry
+
+
1
+ Magento\Sales\Model\Config\Source\Order\Status\NewStatus
-
-
- required-entry
+
+
1
- Magento\Config\Model\Config\Backend\Encrypted
-
+
required-entry
1
+ Magento\Config\Model\Config\Backend\Encrypted
-
+
required-entry
@@ -62,7 +55,7 @@
Magento\Config\Model\Config\Backend\Encrypted
-
+
Set Yes to Enable "As low as %s/installment" label
Magento\Config\Model\Config\Source\Yesno
@@ -70,21 +63,14 @@
1
-
-
-
- 1
-
- Magento\Sales\Model\Config\Source\Order\Status\NewStatus
-
-
+
1
TendoPay\TendopayPayment\Model\System\Config\Source\ApiMode
-
+
Debug logs will be available in file {{base_dir}}/var/log/tendopay.log
@@ -92,34 +78,47 @@
Magento\Config\Model\Config\Source\Yesno
-
+
+
+
+ 1
+
+
+
1
Magento\Payment\Model\Config\Source\Allspecificcountries
-
+
Magento\Directory\Model\Config\Source\Country
1
-
+
1
validate-number
-
+
1
Bearer token
+
+
+ TendoPay\TendopayPayment\Block\Adminhtml\Form\Field\RedirectUrl
+
+ 1
+
+
diff --git a/etc/config.xml b/etc/config.xml
index bddebf8..8abcbca 100644
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -15,19 +15,24 @@
- TendoPay\TendopayPayment\Model\Standard
- 1
- Installments by TendoPay
+ TendoPaymentGatewayFacade
+ 0
+ Pay with TendoPay
Your personal data will be used to process your order, support your experience throughout this website, and for other purposes described in our privacy policy.]]>
1
+ 1
+ authorize_capture
+ 1
+ 1
+ 100
+ PHP
pending
sandbox
- 1
+ 0
0
tendopay/standard/redirect
tendopay/standard/response
- tendopay/standard/cancel
-
+
diff --git a/etc/di.xml b/etc/di.xml
index e9ce28d..6c39746 100644
--- a/etc/di.xml
+++ b/etc/di.xml
@@ -11,9 +11,19 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html
*/
-->
-
+
+
+
+
+ TendoPaymentGatewayConfig
+
+
+
+
+ TendoPaymentGatewayConfig
+
+
@@ -29,4 +39,82 @@ ObjectManager/etc/config.xsd">
+
+
+
+
+ TendoPay\TendopayPayment\Model\ConfigProvider::CODE
+ Magento\Payment\Block\Form
+ TendoPay\TendopayPayment\Block\Adminhtml\Payment\Info
+ TendoPaymentGatewayValueHandlerPool
+ TendoPaymentGatewayCommandPool
+ TendoPaymentValidatorPool
+
+
+
+
+
+
+
+ - TendoPaymentGatewayConfigValueHandler
+
+
+
+
+
+ TendoPaymentGatewayConfig
+
+
+
+
+
+
+ TendoPay\TendopayPayment\Model\ConfigProvider::CODE
+
+
+
+
+
+
+
+ - TendoPaymentSaleCommand
+
+
+
+
+
+
+
+ TendoPay\TendopayPayment\Gateway\Request\AuthorizationRequestBuilder
+ TendoPay\TendopayPayment\Gateway\Response\CompleteSaleHandler
+ TendoPay\TendopayPayment\Gateway\Http\TransferFactory
+ TendoPay\TendopayPayment\Gateway\Http\Client\CaptureClient
+
+
+
+
+
+
+
+ TendoPaymentGatewayConfig
+
+
+
+
+
+
+
+ TendoPaymentGatewayConfig
+
+
+
+
+
+
+ - TendoPaymentCurrencyValidator
+
+
+
+
+
diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml
index 58ccdba..b5ec5d7 100644
--- a/etc/frontend/di.xml
+++ b/etc/frontend/di.xml
@@ -11,8 +11,7 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html
*/
-->
-
+
@@ -20,4 +19,9 @@ ObjectManager/etc/config.xsd">
+
+
+ TendoPaymentGatewayConfig
+
+
diff --git a/etc/module.xml b/etc/module.xml
index 67faff2..e844693 100644
--- a/etc/module.xml
+++ b/etc/module.xml
@@ -13,7 +13,7 @@
-->
-
+
diff --git a/i18n/en_US.csv b/i18n/en_US.csv
new file mode 100755
index 0000000..01dfd35
--- /dev/null
+++ b/i18n/en_US.csv
@@ -0,0 +1,3 @@
+"Continue with TendoPay","Continue with TendoPay"
+"The minimum purchase amount is ₱100. Please increase your cart total.","The minimum purchase amount is ₱100. Please increase your cart total."
+"Min Total Order Amount %1₱","Min Total Order Amount %1₱"
diff --git a/registration.php b/registration.php
old mode 100644
new mode 100755
diff --git a/view/frontend/web/images/tendopay.png b/view/frontend/web/images/tendopay.png
index cb4ecae..ec071d9 100644
Binary files a/view/frontend/web/images/tendopay.png and b/view/frontend/web/images/tendopay.png differ
diff --git a/view/frontend/web/js/view/payment/method-renderer/tendopay-method.js b/view/frontend/web/js/view/payment/method-renderer/tendopay-method.js
index 6682b5a..846bf0f 100644
--- a/view/frontend/web/js/view/payment/method-renderer/tendopay-method.js
+++ b/view/frontend/web/js/view/payment/method-renderer/tendopay-method.js
@@ -10,14 +10,18 @@
*/
define([
'jquery',
+ 'mage/translate',
'Magento_Checkout/js/view/payment/default',
- 'TendoPay_TendopayPayment/js/action/set-payment-method'
-],function ($, Component, setPaymentMethod) {
+ 'Magento_Checkout/js/model/payment/additional-validators',
+ 'Magento_Paypal/js/action/set-payment-method',
+ 'Magento_Customer/js/customer-data',
+ 'Magento_Checkout/js/model/quote'
+], function ($, $t, Component, additionalValidators, setPaymentMethodAction, customerData, quote) {
'use strict';
return Component.extend({
- defaults:{
- 'template':'TendoPay_TendopayPayment/payment/tendopay'
+ defaults: {
+ 'template': 'TendoPay_TendopayPayment/payment/tendopay'
},
initialize: function () {
@@ -65,9 +69,47 @@ define([
getPaymentMethodVisibility: function () {
return window.checkoutConfig.payment.tendopay.visibility;
},
+ getMinTotalAmount: function () {
+ return window.checkoutConfig.payment.tendopay.minTotalAmount;
+ },
+
+ continueToTendoPay() {
+ if (additionalValidators.validate()) {
+ //update payment method information if additional data was changed
+ this.selectPaymentMethod();
+ setPaymentMethodAction(this.messageContainer).done(
+ function () {
+ customerData.invalidate(['cart']);
+ $.mage.redirect(
+ window.checkoutConfig.payment.tendopay.redirectUrl
+ );
+ }
+ );
+
+ return false;
+ }
+ },
+
+ isButtonEnabled() {
+ return this.getCode() === this.isChecked() && this.checkMinTotalAmount();
+ },
+
+ getGrandTotal: function () {
+ let totals = quote.getTotals()();
+
+ if (totals) {
+ return totals['grand_total'];
+ }
+
+ return quote['grand_total'];
+ },
+
+ checkMinTotalAmount() {
+ return this.getGrandTotal() > this.getMinTotalAmount();
+ },
- afterPlaceOrder: function () {
- setPaymentMethod();
+ getMinTotalAmountMessage() {
+ return $t('Min Total Order Amount %1₱').replace('%1', this.getMinTotalAmount);
}
});
});
diff --git a/view/frontend/web/template/payment/tendopay.html b/view/frontend/web/template/payment/tendopay.html
index 80ab181..a839bd5 100644
--- a/view/frontend/web/template/payment/tendopay.html
+++ b/view/frontend/web/template/payment/tendopay.html
@@ -47,16 +47,19 @@
+
+
+
+
+
diff --git a/view/frontend/web/tendopay/css/marketing/popup-box.css b/view/frontend/web/tendopay/css/marketing/popup-box.css
index c2575f8..1615bfe 100644
--- a/view/frontend/web/tendopay/css/marketing/popup-box.css
+++ b/view/frontend/web/tendopay/css/marketing/popup-box.css
@@ -1,215 +1,215 @@
-body {
- margin: 0;
- position: relative;
-}
-
-#tendopay-popup {
- display: flex;
- flex-direction: column;
- position: absolute;
- max-width: 100%;
- width: 100vw;
- height: 100vh;
- top: 50%;
- left: 50%;
- /*-webkit-transform: translate(-50%, -50%);
- -moz-transform: translate(-50%, -50%);
- -ms-transform: translate(-50%, -50%);
- -o-transform: translate(-50%, -50%);
- transform: translate(-50%, -50%);*/
- -webkit-transform: translate(-50%, 0%);
- -moz-transform: translate(-50%, 0%);
- -ms-transform: translate(-50%, 0%);
- -o-transform: translate(-50%, 0%);
- transform: translate(-50%, 0%);
-}
-
-.text-align-center {
- text-align: center;
-}
-
-.mt-3 {
- margin-top: 3rem;
-}
-
-.p-1 {
- padding: 1rem;
-}
-
-.p-2 {
- padding: 2rem;
-}
-
-.p-3 {
- padding: 3rem;
-}
-
-.px-2 {
- padding-left: 2rem;
- padding-right: 2rem;
-}
-
-.px-3 {
- padding-left: 3rem;
- padding-right: 3rem;
-}
-
-.px-4 {
- padding-left: 4rem;
- padding-right: 4rem;
-}
-
-.pt-2 {
- padding-top: 2rem;
-}
-
-.img-logo {
- max-width: 195px;
- height: auto;
-}
-
-.img-icon {
- max-width: 140px;
- height: auto;
-}
-
-.btn {
- border: none;
- color: #000000;
- padding: 20px 35px;
- text-align: center;
- text-decoration: none;
- display: inline-block;
- font-size: 18px;
- border-radius: 5px;
- background-color: #00FFC4;
-}
-
-.font-blue-color {
- color: #25A5F1;
-}
-
-.font-grey-color {
- color: #a0a5aa;
-}
-
-.p-font-text {
- font-size: 14px;
-}
-
-.font-weight-500 {
- font-weight: 500;
-}
-
-.font-family-verdana {
- font-family: verdana, sans-serif;
-}
-
-.background-color-lightgrey {
- background-color: rgba(185, 202, 218, 0.1);
-}
-
-footer {
- background-color: rgba(185, 202, 218, 0.4);
- height: 100%;
-}
-
-.heading-text {
- font-size: 24px;
- letter-spacing: -1px;
- margin: 10px;
-}
-
-.footer {
- color: #000000;
- text-decoration: none;
- height: auto;
- padding: 20px 6rem 20px 6rem;
- letter-spacing: 0.50px;
- font-size: 12px;
- opacity: 0.5;
-}
-
-.page-container {
- position: relative;
-}
-
-.page-container p {
- margin-bottom: 0;
-}
-
-.page-container a {
- margin: 2.33rem auto;
-}
-
-.position-absolute {
- position: absolute;
-}
-
-.w-100 {
- width: 100%;
-}
-
-.bottom-0 {
- bottom: 0;
-}
-
-.d-md-flex {
- display: flex;
-}
-
-.justify-content-center {
- justify-content: center;
-}
-
-.row {
- flex-direction: row;
-}
-
-/**** Mobile Device ****/
-
-@media (max-width: 600px) {
-
- .pb-1 {
- padding-bottom: 1rem;
- }
-
- .d-block {
- display: block;
- }
-
- .img-logo {
- width: 40vw;
- }
-
- .heading-text {
- font-size: 25px;
- }
-
- .footer {
- font-size: 10px;
- padding: 20px 3rem 20px 3rem;
- }
-
- .px-sm-0 {
- padding-left: 0 !important;
- padding-right: 0 !important;
- }
-
- .btn {
- font-size: 12px;
- }
-
- .img-icon {
- width: 90px;
- }
-
- .h3-font-size {
- font-size: 15px;
- }
-
- .p-font-size {
- font-size: 13px;
- }
-
-}
+body {
+ margin: 0;
+ position: relative;
+}
+
+#tendopay-popup {
+ display: flex;
+ flex-direction: column;
+ position: absolute;
+ max-width: 100%;
+ width: 100vw;
+ height: 100vh;
+ top: 50%;
+ left: 50%;
+ /*-webkit-transform: translate(-50%, -50%);
+ -moz-transform: translate(-50%, -50%);
+ -ms-transform: translate(-50%, -50%);
+ -o-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);*/
+ -webkit-transform: translate(-50%, 0%);
+ -moz-transform: translate(-50%, 0%);
+ -ms-transform: translate(-50%, 0%);
+ -o-transform: translate(-50%, 0%);
+ transform: translate(-50%, 0%);
+}
+
+.text-align-center {
+ text-align: center;
+}
+
+.mt-3 {
+ margin-top: 3rem;
+}
+
+.p-1 {
+ padding: 1rem;
+}
+
+.p-2 {
+ padding: 2rem;
+}
+
+.p-3 {
+ padding: 3rem;
+}
+
+.px-2 {
+ padding-left: 2rem;
+ padding-right: 2rem;
+}
+
+.px-3 {
+ padding-left: 3rem;
+ padding-right: 3rem;
+}
+
+.px-4 {
+ padding-left: 4rem;
+ padding-right: 4rem;
+}
+
+.pt-2 {
+ padding-top: 2rem;
+}
+
+.img-logo {
+ max-width: 195px;
+ height: auto;
+}
+
+.img-icon {
+ max-width: 140px;
+ height: auto;
+}
+
+.btn {
+ border: none;
+ color: #000000;
+ padding: 20px 35px;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+ font-size: 18px;
+ border-radius: 5px;
+ background-color: #00FFC4;
+}
+
+.font-blue-color {
+ color: #25A5F1;
+}
+
+.font-grey-color {
+ color: #a0a5aa;
+}
+
+.p-font-text {
+ font-size: 14px;
+}
+
+.font-weight-500 {
+ font-weight: 500;
+}
+
+.font-family-verdana {
+ font-family: verdana, sans-serif;
+}
+
+.background-color-lightgrey {
+ background-color: rgba(185, 202, 218, 0.1);
+}
+
+footer {
+ background-color: rgba(185, 202, 218, 0.4);
+ height: 100%;
+}
+
+.heading-text {
+ font-size: 24px;
+ letter-spacing: -1px;
+ margin: 10px;
+}
+
+.footer {
+ color: #000000;
+ text-decoration: none;
+ height: auto;
+ padding: 20px 6rem 20px 6rem;
+ letter-spacing: 0.50px;
+ font-size: 12px;
+ opacity: 0.5;
+}
+
+.page-container {
+ position: relative;
+}
+
+.page-container p {
+ margin-bottom: 0;
+}
+
+.page-container a {
+ margin: 2.33rem auto;
+}
+
+.position-absolute {
+ position: absolute;
+}
+
+.w-100 {
+ width: 100%;
+}
+
+.bottom-0 {
+ bottom: 0;
+}
+
+.d-md-flex {
+ display: flex;
+}
+
+.justify-content-center {
+ justify-content: center;
+}
+
+.row {
+ flex-direction: row;
+}
+
+/**** Mobile Device ****/
+
+@media (max-width: 600px) {
+
+ .pb-1 {
+ padding-bottom: 1rem;
+ }
+
+ .d-block {
+ display: block;
+ }
+
+ .img-logo {
+ width: 40vw;
+ }
+
+ .heading-text {
+ font-size: 25px;
+ }
+
+ .footer {
+ font-size: 10px;
+ padding: 20px 3rem 20px 3rem;
+ }
+
+ .px-sm-0 {
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+ }
+
+ .btn {
+ font-size: 12px;
+ }
+
+ .img-icon {
+ width: 90px;
+ }
+
+ .h3-font-size {
+ font-size: 15px;
+ }
+
+ .p-font-size {
+ font-size: 13px;
+ }
+
+}