diff --git a/Block/Adminhtml/Config/NotificationEndpoint.php b/Block/Adminhtml/Config/NotificationEndpoint.php new file mode 100644 index 0000000..a87897a --- /dev/null +++ b/Block/Adminhtml/Config/NotificationEndpoint.php @@ -0,0 +1,36 @@ +_midtransHelper = $midtransHelper; + } + + /** + * Retrieve the midtrans Notification endpoint + * + * @param AbstractElement $element + * @return string + */ + protected function _getElementHtml(AbstractElement $element) + { + return $this->_midtransHelper->getNotificationEndpoint(); + } +} diff --git a/Block/Adminhtml/Config/Version.php b/Block/Adminhtml/Config/Version.php new file mode 100644 index 0000000..8e72569 --- /dev/null +++ b/Block/Adminhtml/Config/Version.php @@ -0,0 +1,36 @@ +_midtransHelper = $midtransHelper; + } + + /** + * Retrieve the setup version of the extension + * + * @param AbstractElement $element + * @return string + */ + protected function _getElementHtml(AbstractElement $element) + { + return $this->_midtransHelper->getModuleVersion(); + } +} diff --git a/Controller/Payment/AbstractAction.php b/Controller/Payment/AbstractAction.php index c2d443f..7e16f67 100644 --- a/Controller/Payment/AbstractAction.php +++ b/Controller/Payment/AbstractAction.php @@ -481,8 +481,8 @@ public function getPayload($config) if ($config['one_click']) { $payloads['user_id'] = crypt($order_billing_address->getEmail(), $this->data->getServerKey($paymentCode)); } - if (!empty($customExpiry)) { - $customExpiry = explode(" ", $customExpiry); + if (isset($config['custom_expiry'])) { + $customExpiry = explode(" ", $config['custom_expiry']); $expiry_unit = $customExpiry[1]; $expiry_duration = (int)$customExpiry[0]; @@ -1036,10 +1036,8 @@ public function isContainDownloadableProduct() //look for downloadable products if ($item->getProductType() === 'downloadable') { return true; - break; } else { return false; - break; } } } diff --git a/Controller/Payment/Notification.php b/Controller/Payment/Notification.php index b2bae9d..d38fc70 100755 --- a/Controller/Payment/Notification.php +++ b/Controller/Payment/Notification.php @@ -48,7 +48,7 @@ public function execute() if ($transaction == 'capture') { if ($fraud == 'challenge') { $order_note = $note_prefix . 'Payment status challenged. Please take action on your Merchant Administration Portal - ' . $payment_type; - $this->setOrderStateAndStatus($orderId, Order::STATE_PAYMENT_REVIEW, $order_note, $trxId); + $this->setOrderStateAndStatus($orderId, Order::STATE_PAYMENT_REVIEW, $order_note); } elseif ($fraud == 'accept') { $order_note = $note_prefix . 'Payment Completed - ' . $payment_type; if ($order->canInvoice() && !$order->hasInvoices()) { @@ -66,7 +66,7 @@ public function execute() } } elseif ($transaction == 'pending') { $order_note = $note_prefix . 'Awating Payment - ' . $payment_type; - $this->setOrderStateAndStatus($orderId, Order::STATE_PENDING_PAYMENT, $order_note, $trxId); + $this->setOrderStateAndStatus($orderId, Order::STATE_PENDING_PAYMENT, $order_note); } elseif ($transaction == 'cancel') { if ($order->canCancel()) { $order_note = $note_prefix . 'Canceled Payment - ' . $payment_type; @@ -81,7 +81,7 @@ public function execute() $order_note = $note_prefix . 'Payment Deny - ' . $payment_type; $order->addStatusToHistory(Order::STATE_PAYMENT_REVIEW, $order_note, false); } elseif ($transaction == 'refund' || $transaction == 'partial_refund') { - $isFullRefund = ($transaction == 'refund') ? true : false; + $isFullRefund = $transaction == 'refund'; /** * Get last array object from refunds array and get the value from last refund object diff --git a/Controller/Payment/Redirect.php b/Controller/Payment/Redirect.php index 1f5aac6..5831581 100755 --- a/Controller/Payment/Redirect.php +++ b/Controller/Payment/Redirect.php @@ -4,26 +4,32 @@ use Exception; use Magento\Framework\Controller\ResultFactory; -use Midtrans\Snap\Gateway\SnapApi; use Midtrans\Snap\Gateway\Config\Config; +use Midtrans\Snap\Gateway\SnapApi; class Redirect extends AbstractAction { public function execute() { - $paymentCode = $this->getCode(); - $requestConfig = $this->getData()->getRequestConfig($paymentCode); - $enableRedirect = $this->getData()->isRedirect(); + try { + $paymentCode = $this->getCode(); + $requestConfig = $this->getData()->getRequestConfig($paymentCode); + $enableRedirect = $this->getData()->isRedirect(); - $payloads = $this->getPayload($requestConfig); - $is3ds = $requestConfig['is3ds']; + $payloads = $this->getPayload($requestConfig); + $is3ds = $requestConfig['is3ds']; + $isProduction = $this->getData()->isProduction(); - Config::$is3ds = $is3ds; - Config::$isProduction = $this->getData()->isProduction(); - Config::$serverKey = $this->getData()->getServerKey($paymentCode); - Config::$isSanitized = false; + Config::$isProduction = $isProduction; + Config::$serverKey = $this->getData()->getServerKey($paymentCode); + Config::$isSanitized = true; + Config::$is3ds = $is3ds; + + /*Override notification, if override notification from admin setting is active (default is active) */ + if ($this->getData()->isOverrideNotification() && $this->getData()->getNotificationEndpoint() != null) { + Config::$overrideNotifUrl = $this->getData()->getNotificationEndpoint(); + } - try { $_info = 'Info - Payloads: ' . print_r($payloads, true); $this->_midtransLogger->midtransRequest($_info); diff --git a/Gateway/Config/Config.php b/Gateway/Config/Config.php index 7ad4c46..ab1a59b 100755 --- a/Gateway/Config/Config.php +++ b/Gateway/Config/Config.php @@ -32,6 +32,18 @@ class Config * @static */ public static $is3ds = false; + /** + * Set Append URL notification + * + * @static + */ + public static $appendNotifUrl; + /** + * Set Override URL notification + * + * @static + */ + public static $overrideNotifUrl; /** * Enable request params sanitizer (validate and modify charge request params). * See Midtrans_Sanitizer for more details @@ -44,7 +56,7 @@ class Config * * @static */ - public static $curlOptions = array(); + public static $curlOptions = []; const SANDBOX_BASE_URL = 'https://api.sandbox.midtrans.com/v2'; const PRODUCTION_BASE_URL = 'https://api.midtrans.com/v2'; diff --git a/Gateway/CoreApi.php b/Gateway/CoreApi.php index 9a957ed..1a94795 100755 --- a/Gateway/CoreApi.php +++ b/Gateway/CoreApi.php @@ -3,8 +3,9 @@ namespace Midtrans\Snap\Gateway; use Midtrans\Snap\Gateway\Config\Config; -use Midtrans\Snap\Gateway\Utility\Sanitizer; use Midtrans\Snap\Gateway\Http\Client\ApiRequestor; +use Midtrans\Snap\Gateway\Utility\Sanitizer; + /** * Provide charge and capture functions for Core API */ @@ -19,11 +20,11 @@ class CoreApi */ public static function charge($params) { - $payloads = array( + $payloads = [ 'payment_type' => 'credit_card' - ); + ]; - if (array_key_exists('item_details', $params)) { + if (isset($params['item_details'])) { $gross_amount = 0; foreach ($params['item_details'] as $item) { $gross_amount += $item['quantity'] * $item['price']; @@ -37,13 +38,19 @@ public static function charge($params) Sanitizer::jsonRequest($payloads); } - $result = ApiRequestor::post( + if (Config::$appendNotifUrl) { + Config::$curlOptions[CURLOPT_HTTPHEADER][] = 'X-Append-Notification: ' . Config::$appendNotifUrl; + } + + if (Config::$overrideNotifUrl) { + Config::$curlOptions[CURLOPT_HTTPHEADER][] = 'X-Override-Notification: ' . Config::$overrideNotifUrl; + } + + return ApiRequestor::post( Config::getBaseUrl() . '/charge', Config::$serverKey, $payloads ); - - return $result; } /** @@ -55,16 +62,14 @@ public static function charge($params) */ public static function capture($param) { - $payloads = array( + $payloads = [ 'transaction_id' => $param, - ); + ]; - $result = ApiRequestor::post( + return ApiRequestor::post( Config::getBaseUrl() . '/capture', Config::$serverKey, $payloads ); - - return $result; } } diff --git a/Gateway/Http/Client/ApiRequestor.php b/Gateway/Http/Client/ApiRequestor.php index f491a60..5a671c4 100755 --- a/Gateway/Http/Client/ApiRequestor.php +++ b/Gateway/Http/Client/ApiRequestor.php @@ -3,6 +3,7 @@ namespace Midtrans\Snap\Gateway\Http\Client; use Midtrans\Snap\Gateway\Config\Config; + /** * Send request to Midtrans API * Better don't use this class directly, use CoreApi, Transaction @@ -53,26 +54,26 @@ public static function remoteCall($url, $server_key, $data_hash, $post = true) { $ch = curl_init(); - $curl_options = array( + $curl_options = [ CURLOPT_URL => $url, - CURLOPT_HTTPHEADER => array( + CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json', 'user-agent : Magento 2 Module', - 'x-plugin-name : midtrans-magento2', + 'x-plugin-name : midtrans-magento-2.4.3', 'Authorization: Basic ' . base64_encode($server_key . ':') - ), + ], CURLOPT_RETURNTRANSFER => 1 - ); + ]; // merging with Config::$curlOptions if (count(Config::$curlOptions)) { // We need to combine headers manually, because it's array and it will no be merged if (Config::$curlOptions[CURLOPT_HTTPHEADER]) { $mergedHeders = array_merge($curl_options[CURLOPT_HTTPHEADER], Config::$curlOptions[CURLOPT_HTTPHEADER]); - $headerOptions = array( CURLOPT_HTTPHEADER => $mergedHeders ); + $headerOptions = [ CURLOPT_HTTPHEADER => $mergedHeders ]; } else { - $mergedHeders = array(); + $mergedHeders = []; } $curl_options = array_replace_recursive($curl_options, Config::$curlOptions, $headerOptions); @@ -99,16 +100,15 @@ public static function remoteCall($url, $server_key, $data_hash, $post = true) // curl_close($ch); } - if ($result === false) { throw new \Exception('CURL Error: ' . curl_error($ch), curl_errno($ch)); } else { try { $result_array = json_decode($result); } catch (\Exception $e) { - throw new \Exception("API Request Error unable to json_decode API response: ".$result . ' | Request url: '.$url); + throw new \Exception("API Request Error unable to json_decode API response: " . $result . ' | Request url: ' . $url); } - if (!in_array($result_array->status_code, array(200, 201, 202, 407))) { + if (!in_array($result_array->status_code, [200, 201, 202, 407])) { $message = 'Midtrans Error (' . $result_array->status_code . '): ' . $result_array->status_message; if (isset($result_array->validation_messages)) { @@ -126,13 +126,13 @@ public static function remoteCall($url, $server_key, $data_hash, $post = true) private static function processStubed($curl, $url, $server_key, $data_hash, $post) { - VT_Tests::$lastHttpRequest = array( + VT_Tests::$lastHttpRequest = [ "url" => $url, "server_key" => $server_key, "data_hash" => $data_hash, "post" => $post, "curl" => $curl - ); + ]; return VT_Tests::$stubHttpResponse; } diff --git a/Gateway/Http/Client/SnapApiRequestor.php b/Gateway/Http/Client/SnapApiRequestor.php index 18126e0..b3e0b11 100755 --- a/Gateway/Http/Client/SnapApiRequestor.php +++ b/Gateway/Http/Client/SnapApiRequestor.php @@ -3,6 +3,7 @@ namespace Midtrans\Snap\Gateway\Http\Client; use Midtrans\Snap\Gateway\Config\Config; + /** * Send request to Snap API * Better don't use this class directly, use Snap @@ -52,27 +53,27 @@ public static function remoteCall($url, $server_key, $data_hash, $post = true) { $ch = curl_init(); - $curl_options = array( + $curl_options = [ CURLOPT_URL => $url, - CURLOPT_HTTPHEADER => array( + CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Accept: application/json', 'user-agent : Magento 2 Module', - 'x-plugin-name : midtrans-magento2', + 'x-plugin-name : midtrans-magento2-v2.4.3', 'Authorization: Basic ' . base64_encode($server_key . ':') - ), + ], CURLOPT_RETURNTRANSFER => 1, // CURLOPT_CAINFO => dirname(__FILE__) . "/../data/cacert.pem" - ); + ]; // merging with Config::$curlOptions if (count(Config::$curlOptions)) { // We need to combine headers manually, because it's array and it will no be merged if (Config::$curlOptions[CURLOPT_HTTPHEADER]) { $mergedHeders = array_merge($curl_options[CURLOPT_HTTPHEADER], Config::$curlOptions[CURLOPT_HTTPHEADER]); - $headerOptions = array( CURLOPT_HTTPHEADER => $mergedHeders ); + $headerOptions = [ CURLOPT_HTTPHEADER => $mergedHeders ]; } else { - $mergedHeders = array(); + $mergedHeders = []; } $curl_options = array_replace_recursive($curl_options, Config::$curlOptions, $headerOptions); @@ -107,12 +108,12 @@ public static function remoteCall($url, $server_key, $data_hash, $post = true) try { $result_array = json_decode($result); } catch (\Exception $e) { - $message = "API Request Error unable to json_decode API response: ".$result . ' | Request url: '.$url; + $message = "API Request Error unable to json_decode API response: " . $result . ' | Request url: ' . $url; throw new \Exception($message); } if ($info['http_code'] != 201) { $message = 'Midtrans Error (' . $info['http_code'] . '): ' - . $result . ' | Request url: '.$url; + . $result . ' | Request url: ' . $url; throw new \Exception($message, $info['http_code']); } else { return $result_array; @@ -122,13 +123,13 @@ public static function remoteCall($url, $server_key, $data_hash, $post = true) private static function processStubed($curl, $url, $server_key, $data_hash, $post) { - VT_Tests::$lastHttpRequest = array( + VT_Tests::$lastHttpRequest = [ "url" => $url, "server_key" => $server_key, "data_hash" => $data_hash, "post" => $post, "curl" => $curl - ); + ]; return VT_Tests::$stubHttpResponse; } diff --git a/Gateway/Notification.php b/Gateway/Notification.php index 2f5ac50..23a3a26 100755 --- a/Gateway/Notification.php +++ b/Gateway/Notification.php @@ -29,7 +29,7 @@ public function __construct($input_source = "php://input") public function __get($name) { - if (array_key_exists($name, $this->response)) { + if (isset($this->response->$name)) { return $this->response->$name; } } diff --git a/Gateway/SnapApi.php b/Gateway/SnapApi.php index a07441e..681b3c5 100755 --- a/Gateway/SnapApi.php +++ b/Gateway/SnapApi.php @@ -3,13 +3,13 @@ namespace Midtrans\Snap\Gateway; use Midtrans\Snap\Gateway\Config\Config; -use Midtrans\Snap\Gateway\Utility\Sanitizer; use Midtrans\Snap\Gateway\Http\Client\SnapApiRequestor; +use Midtrans\Snap\Gateway\Utility\Sanitizer; + /** * Create Snap payment page and return snap token */ class SnapApi - { /** * Create Snap payment page @@ -31,7 +31,7 @@ class SnapApi * * @param array $params Payment options * @return string Snap token. - * @throws Exception curl error or midtrans error + * @throws Exception|\Exception curl error or midtrans error */ public static function getSnapToken($params) { @@ -55,17 +55,17 @@ public static function getSnapToken($params) * * @param array $params Payment options * @return object Snap response (token and redirect_url). - * @throws Exception curl error or midtrans error + * @throws Exception|\Exception curl error or midtrans error */ public static function createTransaction($params) { - $payloads = array( - 'credit_card' => array( + $payloads = [ + 'credit_card' => [ 'secure' => Config::$is3ds - ) - ); + ] + ]; - if (array_key_exists('item_details', $params)) { + if (isset($params['item_details'])) { $gross_amount = 0; foreach ($params['item_details'] as $item) { $gross_amount += $item['quantity'] * $item['price']; @@ -77,14 +77,20 @@ public static function createTransaction($params) Sanitizer::jsonRequest($params); } + if (Config::$appendNotifUrl) { + Config::$curlOptions[CURLOPT_HTTPHEADER][] = 'X-Append-Notification: ' . Config::$appendNotifUrl; + } + + if (Config::$overrideNotifUrl) { + Config::$curlOptions[CURLOPT_HTTPHEADER][] = 'X-Override-Notification: ' . Config::$overrideNotifUrl; + } + $params = array_replace_recursive($payloads, $params); - $result = SnapApiRequestor::post( + return SnapApiRequestor::post( Config::getSnapBaseUrl() . '/transactions', Config::$serverKey, $params ); - - return $result; } } diff --git a/Gateway/Utility/Sanitizer.php b/Gateway/Utility/Sanitizer.php index a548d99..2f861f6 100755 --- a/Gateway/Utility/Sanitizer.php +++ b/Gateway/Utility/Sanitizer.php @@ -15,7 +15,7 @@ class Sanitizer public function __construct() { - $this->filters = array(); + $this->filters = []; } /** @@ -25,9 +25,9 @@ public function __construct() */ public static function jsonRequest(&$json) { - $keys = array('item_details', 'customer_details'); + $keys = ['item_details', 'customer_details']; foreach ($keys as $key) { - if (!array_key_exists($key, $json)) continue; + if (!isset($json[$key])) continue; $camel = static::upperCamelize($key); $function = "field$camel"; @@ -38,11 +38,11 @@ public static function jsonRequest(&$json) private static function fieldItemDetails(&$items) { foreach ($items as &$item) { - $id = new self; + $id = new self(); $item['id'] = $id ->maxLength(50) ->apply($item['id']); - $name = new self; + $name = new self(); $item['name'] = $name ->maxLength(50) ->apply($item['name']); @@ -51,17 +51,17 @@ private static function fieldItemDetails(&$items) private static function fieldCustomerDetails(&$field) { - $first_name = new self; + $first_name = new self(); $field['first_name'] = $first_name ->maxLength(20) ->apply($field['first_name']); - if (array_key_exists('last_name', $field)) { - $last_name = new self; + if (isset($field['last_name'])) { + $last_name = new self(); $field['last_name'] = $last_name ->maxLength(20) ->apply($field['last_name']); } - $email = new self; + $email = new self(); $field['email'] = $email ->maxLength(45) ->apply($field['email']); @@ -69,45 +69,44 @@ private static function fieldCustomerDetails(&$field) static::fieldPhone($field['phone']); if (!empty($field['billing_address']) || !empty($field['shipping_address'])) { - $keys = array('billing_address', 'shipping_address'); + $keys = ['billing_address', 'shipping_address']; foreach ($keys as $key) { - if (!array_key_exists($key, $field)) continue; + if (!isset($field[$key])) continue; $camel = static::upperCamelize($key); $function = "field$camel"; static::$function($field[$key]); } } - } private static function fieldBillingAddress(&$field) { - $fields = array( + $fields = [ 'first_name' => 20, 'last_name' => 20, 'address' => 200, 'city' => 20, 'country_code' => 10 - ); + ]; foreach ($fields as $key => $value) { - if (array_key_exists($key, $field)) { - $self = new self; + if (isset($field[$key])) { + $self = new self(); $field[$key] = $self ->maxLength($value) ->apply($field[$key]); } } - if (array_key_exists('postal_code', $field)) { - $postal_code = new self; + if (isset($field['postal_code'])) { + $postal_code = new self(); $field['postal_code'] = $postal_code ->whitelist('A-Za-z0-9\\- ') ->maxLength(10) ->apply($field['postal_code']); } - if (array_key_exists('phone', $field)) { + if (isset($field['phone'])) { static::fieldPhone($field['phone']); } } @@ -119,15 +118,17 @@ private static function fieldShippingAddress(&$field) private static function fieldPhone(&$field) { - $plus = substr($field, 0, 1) === '+' ? true : false; - $self = new self; + $plus = substr($field, 0, 1) === '+'; + $self = new self(); $field = $self ->whitelist('\\d\\-\\(\\) ') ->maxLength(19) ->apply($field); - if ($plus) $field = '+' . $field; - $self = new self; + if ($plus) { + $field = '+' . $field; + } + $self = new self(); $field = $self ->maxLength(19) ->apply($field); diff --git a/Helper/Data.php b/Helper/Data.php index b755e4b..d1b34cd 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -2,6 +2,7 @@ namespace Midtrans\Snap\Helper; +use Magento\Framework\Component\ComponentRegistrarInterface; use Magento\Framework\Encryption\EncryptorInterface; use Midtrans\Snap\Model\Config\Source\Payment\Settings; @@ -10,25 +11,50 @@ class Data private $settings; private $_encryptor; + /** + * @var ComponentRegistrarInterface + */ + private $componentRegistrar; + + /** + * Data constructor. + * @param Settings $settings + * @param EncryptorInterface $encryptor + * @param ComponentRegistrarInterface $componentRegistrar + */ public function __construct( Settings $settings, - EncryptorInterface $encryptor - ) - { + EncryptorInterface $encryptor, + ComponentRegistrarInterface $componentRegistrar + ) { $this->settings = $settings; $this->_encryptor = $encryptor; + $this->componentRegistrar = $componentRegistrar; } - public function getMixPanelKey() { + public function getMixPanelKey() + { return $this->isProduction() == true ? '17253088ed3a39b1e2bd2cbcfeca939a' : '9dcba9b440c831d517e8ff1beff40bd9'; } - public function enableLog() { + public function getNotificationEndpoint() + { + return $this->settings->getNotificationEndpoint(); + } + + public function isOverrideNotification() + { + return $this->settings->isOverrideNotification(); + } + + public function enableLog() + { $enableLog = $this->settings->enableLog(); return $enableLog; } - public function getMerchantId($code) { + public function getMerchantId($code) + { if ($code == 'snap') { return $this->settings->getMerchantId(); } elseif ($code == 'specific') { @@ -40,17 +66,20 @@ public function getMerchantId($code) { } } - public function isRedirect() { + public function isRedirect() + { $isRedirect = $this->settings->isRedirect(); return $isRedirect; } - public function isProduction() { + public function isProduction() + { $isProduction = $this->settings->isProduction(); return $isProduction; } - public function getServerKey($paymentCode) { + public function getServerKey($paymentCode) + { if ($paymentCode == 'snap') { $serverKey = $this->settings->getDefaultServerKey(); $key = $this->_encryptor->decrypt($serverKey); @@ -70,7 +99,8 @@ public function getServerKey($paymentCode) { } } - public function getClientKey($paymentCode) { + public function getClientKey($paymentCode) + { if ($paymentCode == 'snap') { $clientKey = $this->settings->getDefaultClientKey(); $key = $this->_encryptor->decrypt($clientKey); @@ -90,15 +120,33 @@ public function getClientKey($paymentCode) { } } - public function getRequestConfig($paymentCode) { + public function getRequestConfig($paymentCode) + { if ($paymentCode == 'snap') { return $this->settings->getConfigSnap(); - } else if ($paymentCode == 'specific') { + } elseif ($paymentCode == 'specific') { return $this->settings->getConfigSpecific(); - } else if ($paymentCode == 'installment') { + } elseif ($paymentCode == 'installment') { return $this->settings->getConfigInstallment(); - } else if ($paymentCode == 'offline') { + } elseif ($paymentCode == 'offline') { return $this->settings->getConfigOffline(); } } + + public function getModuleVersion() + { + $moduleDir = $this->componentRegistrar->getPath( + \Magento\Framework\Component\ComponentRegistrar::MODULE, + 'Midtrans_Snap' + ); + + $composerJson = file_get_contents($moduleDir . '/composer.json'); + $composerJson = json_decode($composerJson, true); + + if (empty($composerJson['version'])) { + return "Version is not available in composer.json"; + } + + return $composerJson['version']; + } } diff --git a/Model/Config/Source/Field/ModuleVersion.php b/Model/Config/Source/Field/ModuleVersion.php deleted file mode 100644 index 84eb3be..0000000 --- a/Model/Config/Source/Field/ModuleVersion.php +++ /dev/null @@ -1,65 +0,0 @@ -moduleResource = $moduleResource; - - parent::__construct( - $context, - $registry, - $config, - $cacheTypeList, - $resource, - $resourceCollection, - $data - ); - } - - /** - * Inject current installed module version as the config value. - * @return void - */ - public function afterLoad() - { - $composer = file_get_contents(dirname(__FILE__) . '/../../../../composer.json'); - $json = json_decode($composer, true); // decode the JSON into an associative array - $version = $json['version']; - $this->setValue($version); - } -} diff --git a/Model/Config/Source/Payment/AbstractPayment.php b/Model/Config/Source/Payment/AbstractPayment.php index 38fcbab..fa8fff1 100644 --- a/Model/Config/Source/Payment/AbstractPayment.php +++ b/Model/Config/Source/Payment/AbstractPayment.php @@ -4,6 +4,7 @@ use Magento\Framework\Event\ManagerInterface; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\UrlInterface; use Magento\Payment\Gateway\Command\CommandManagerInterface; use Magento\Payment\Gateway\Command\CommandPoolInterface; use Magento\Payment\Gateway\Config\ValueHandlerPoolInterface; @@ -13,6 +14,7 @@ use Magento\Payment\Model\Method\Adapter; use Magento\Payment\Model\MethodInterface; use Magento\Sales\Model\Order; +use Magento\Store\Model\StoreManagerInterface; use Midtrans\Snap\Gateway\Config\Config; use Midtrans\Snap\Gateway\Transaction; use Midtrans\Snap\Helper\Data; @@ -65,12 +67,24 @@ class AbstractPayment extends Adapter */ protected $midtransLogger; + /** + * @var UrlInterface + */ + public $urlInterface; + + /** + * @var StoreManagerInterface + */ + public $storeManager; + /** * AbstractPayment constructor. * @param ManagerInterface $eventManager * @param ValueHandlerPoolInterface $valueHandlerPool * @param PaymentDataObjectFactory $paymentDataObjectFactory * @param Data $dataConfig + * @param UrlInterface $urlInterface + * @param StoreManagerInterface $storeManager * @param MidtransLogger $midtransLogger * @param string $code * @param string $formBlockType @@ -84,6 +98,8 @@ public function __construct( ValueHandlerPoolInterface $valueHandlerPool, PaymentDataObjectFactory $paymentDataObjectFactory, Data $dataConfig, + UrlInterface $urlInterface, + StoreManagerInterface $storeManager, MidtransLogger $midtransLogger, $code, $formBlockType, @@ -104,6 +120,8 @@ public function __construct( $commandExecutor ); $this->dataConfig = $dataConfig; + $this->urlInterface = $urlInterface; + $this->storeManager = $storeManager; $this->midtransLogger = $midtransLogger; } @@ -124,6 +142,11 @@ public function refund(InfoInterface $payment, $amount) $orderId = $order->getRealOrderId(); Config::$serverKey = $this->dataConfig->getServerKey($paymentCode); + + /*Override notification, if override notification from admin setting is active (default is active) */ + if ($this->dataConfig->isOverrideNotification() && $this->dataConfig->getNotificationEndpoint() != null) { + Config::$overrideNotifUrl = $this->dataConfig->getNotificationEndpoint(); + } $transaction = new Transaction(); // Check is full refund or partial diff --git a/Model/Config/Source/Payment/Settings.php b/Model/Config/Source/Payment/Settings.php index ee9be6a..7bd0acc 100644 --- a/Model/Config/Source/Payment/Settings.php +++ b/Model/Config/Source/Payment/Settings.php @@ -4,7 +4,9 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; class Settings extends AbstractPayment { @@ -15,13 +17,16 @@ class Settings extends AbstractPayment public $code = self::SETTINGS_PAYMENT_CODE; protected $_scopeConfig; + protected $_storeManager; /** * Settings constructor. * @param ScopeConfigInterface $scopeConfig + * @param StoreManagerInterface $storeManager */ - public function __construct(ScopeConfigInterface $scopeConfig) + public function __construct(ScopeConfigInterface $scopeConfig, StoreManagerInterface $storeManager) { + $this->_storeManager = $storeManager; $this->_scopeConfig = $scopeConfig; } @@ -75,6 +80,20 @@ public function getOrderStatus() return $this->getDataConfig('payment/settings/order_status'); } + public function getNotificationEndpoint() + { + try { + return $this->_storeManager->getStore()->getBaseUrl() . 'snap/payment/notification'; + } catch (NoSuchEntityException $e) { + return null; + } + } + + public function isOverrideNotification() + { + return $this->getDataConfig('payment/settings/notification_override') == 1; + } + public function getConfigSnap() { $config = []; diff --git a/README.md b/README.md index 6a682b1..a6b2249 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,27 @@ Midtrans ❤️ Magento! Midtrans is highly concerned with customer experience (UX). We strive to make payments simple for both the merchant and customers. With this plugin, you can make your Magento store using Midtrans payment. ## Requirements: -* An online store with Magento infrastructure. This plugin is tested with Magento v2.4 +* An online store with Magento infrastructure. This plugin is tested with Magento v2.4.1 * PHP v5.6 or greater. * MySQL v5.7 or greater. * Midtrans plugin for Magento v2.x [ [Github](https://github.com/Midtrans/Midtrans-Magento2) | [Zip](https://github.com/Midtrans/Midtrans-Magento2/archive/master.zip) ] -* This plugin supports Magento2 version 2.1.0, 2.2.0, 2.3.4 and higher. +* This plugin supports Magento2 version 2.1.0 - 2.4.1 and higher. # How to install the plugins ## Install Midtrans Snap plugins through Composer Before you begin to install through the composer, you need Magento marketplace account and make sure that you have installed Composer. In your terminal, go to the Magento folder and run the following commands: 1. Install the plugins: `composer require midtrans/snap` -2. Enable the plugin: `bin/magento module:enable Midtrans_Snap` +2. Enable the plugin: `bin/magento module:enable Midtrans_Snap --clear-static-content` 3. Execute upgrade script : `bin/magento setup:upgrade` -4. Flush cache storage : `bin/magento cache:flush` +4. Flush cache storage : `bin/magento cache:clean` +5. Check the module status: `bin/magento module:status Midtrans_Snap` + +>Note: If you do have a previous version installed and upgrade the plugins to the latest version. After upgrade our plugins, You need to run `bin/magento setup:upgrade` and flush cache `bin/magento cachce:clean`. ## Install Midtrans Snap plugins through Magento marketplace -You can install Midtrans Snap plugins through Magento Marketplace. Please, visit Midtrans on [Magento Marketplace](https://marketplace.magento.com/midtrans-snap.html) and follow step-by-step installation instructions from the [Official Magento extension docs](https://docs.magento.com/user-guide/system/web-setup-extension-manager.html) +You can install Midtrans Snap plugins through Magento Marketplace. Please, visit Midtrans on [Magento Marketplace](https://marketplace.magento.com/midtrans-snap.html) and follow step-by-step installation instructions from the [Official Magento extension docs](https://devdocs.magento.com/extensions/install) ## Install Midtrans Snap plugins from GitHub project @@ -31,11 +34,13 @@ With these steps, you can custom/modify our Magento plugins to handle the busine 4. Copy the app folders into the Magento root folder. 5. Run this command on terminal - `bin/magento module:enable Midtrans_Snap` + `bin/magento module:enable Midtrans_Snap --clear-static-content` `bin/magento setup:upgrade` - `bin/magento cache:flush` + `bin/magento cache:clean` + + `bin/magento module:status Midtrans_Snap` # Plugin Usage Instruction @@ -96,7 +101,7 @@ In the Midtrans Magento plugins we have 4 option to use Snap model payment metho >Note: You can use different Midtrans Account for every Snap model payment method, should configure the access-key in Optional section `“Use different Midtrans account”`. If the optional access-key is empty, the plugins will automatically use access key on Basic Settings. ->INFO: The built-in BCA Klikpay landing page for now will only use server key from basic settings of Snap payment integration +>INFO: The built-in BCA Klikpay landing page for now will only use server key from basic settings of Snap payment integration, and our plugins still not support for multishipping order In case you need to customize configuration these field are configurable, and described as follows: diff --git a/composer.json b/composer.json index 0c8ff63..19c5762 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "midtrans/snap", "description": "Midtrans Accept Online Payment Magento 2 module", "type": "magento2-module", - "version": "2.3.3", + "version": "2.4.3", "authors" : [ { "name": "Zaki Ibrahim", diff --git a/etc/adminhtml/system/midtrans_getting_started.xml b/etc/adminhtml/system/midtrans_getting_started.xml index 498f0aa..445e1c0 100644 --- a/etc/adminhtml/system/midtrans_getting_started.xml +++ b/etc/adminhtml/system/midtrans_getting_started.xml @@ -10,11 +10,11 @@
  • Get Sandbox Access Key or Get Production Access Key
  • Midtrans our documentation web website or email support@midtrans.com.

    +

    If you have any further questions, please visit our documentation web website or email support@midtrans.com.

    ]]> - Midtrans\Snap\Model\Config\Source\Field\ModuleVersion + Midtrans\Snap\Block\Adminhtml\Config\Version diff --git a/etc/adminhtml/system/midtrans_settings.xml b/etc/adminhtml/system/midtrans_settings.xml index a027455..92bb880 100644 --- a/etc/adminhtml/system/midtrans_settings.xml +++ b/etc/adminhtml/system/midtrans_settings.xml @@ -13,6 +13,7 @@ Magento\Config\Model\Config\Backend\Encrypted + no-whitespace 1 @@ -20,6 +21,7 @@ Magento\Config\Model\Config\Backend\Encrypted + no-whitespace 1 @@ -27,6 +29,7 @@ Magento\Config\Model\Config\Backend\Encrypted + no-whitespace 0 @@ -34,6 +37,7 @@ Magento\Config\Model\Config\Backend\Encrypted + no-whitespace 0 @@ -51,6 +55,23 @@ Magento\Sales\Model\Config\Source\Order\Status\NewStatus payment/settings/order_status + + + MAP configuration page. In case this method fails, try disabling override notification feature.]]> + 1 + Magento\Config\Block\System\Config\Form\Fieldset + + + Midtrans\Snap\Block\Adminhtml\Config\NotificationEndpoint + Payment Notification URL field in the Midtrans configuration page. The notification URL value is an autogenerated attempt based on Magento default config, it may generate invalid url in some extreme cases of custom config. Use this as reference only.]]> + + + + Magento\Config\Model\Config\Source\Yesno + payment/settings/notification_override + + + Magento\Config\Block\System\Config\Form\Fieldset diff --git a/etc/config.xml b/etc/config.xml index 489215c..b34c340 100755 --- a/etc/config.xml +++ b/etc/config.xml @@ -11,6 +11,7 @@ 0 pending + 1 1 1 1 diff --git a/etc/di.xml b/etc/di.xml index e5c879c..dfbcf0e 100755 --- a/etc/di.xml +++ b/etc/di.xml @@ -270,6 +270,7 @@ Magento\Framework\App\Config\ScopeConfigInterface + Midtrans\Snap\Helper\Data @@ -285,9 +286,4 @@ - - - Midtrans\Snap\Helper\Data - -