From b7d54e92b97ec85ab5c15e1fcb624cc9211b1bba Mon Sep 17 00:00:00 2001 From: Ariful islam Date: Wed, 24 Aug 2022 18:17:00 +0600 Subject: [PATCH] verifypayment method modified --- composer.json | 4 +- composer.lock | 517 +++++++++++++++++++++++- readme.md | 4 +- src/Exception/ExceptionHandler.php | 2 +- src/Exception/NagadPaymentException.php | 31 ++ src/Helper.php | 57 ++- src/RequestHandler.php | 5 +- src/lib/Key.php | 29 +- 8 files changed, 620 insertions(+), 29 deletions(-) create mode 100644 src/Exception/NagadPaymentException.php diff --git a/composer.json b/composer.json index 1160a9c..683bee4 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,9 @@ "require": { "php": "^7.0|^8.0|^8.1", "ext-curl": "*", - "ext-json": "*" + "ext-json": "*", + "nesbot/carbon": "^2.59", + "ext-openssl": "*" }, "description": "This is Bangladeshi nagad payment gateway api development library. This library can be used easily as dependency in your php application.", "keywords": [ diff --git a/composer.lock b/composer.lock index 41be14b..2cb99f8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,519 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "74ce34d177178a060eb596e43553a982", - "packages": [], + "content-hash": "7684578ef121b77c250cebbb8e1f216f", + "packages": [ + { + "name": "nesbot/carbon", + "version": "2.59.1", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a9000603ea337c8df16cc41f8b6be95a65f4d0f5", + "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.0", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2022-06-29T21:43:55+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-10T07:21:04+00:00" + }, + { + "name": "symfony/translation", + "version": "v5.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "1639abc1177d26bcd4320e535e664cef067ab0ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/1639abc1177d26bcd4320e535e664cef067ab0ca", + "reference": "1639abc1177d26bcd4320e535e664cef067ab0ca", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation-contracts": "^2.3" + }, + "conflict": { + "symfony/config": "<4.4", + "symfony/console": "<5.3", + "symfony/dependency-injection": "<5.0", + "symfony/http-kernel": "<5.0", + "symfony/twig-bundle": "<5.0", + "symfony/yaml": "<4.4" + }, + "provide": { + "symfony/translation-implementation": "2.3" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.0|^6.0", + "symfony/intl": "^4.4|^5.0|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v5.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-06T12:33:37+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/136b19dd05cdf0709db6537d058bcab6dd6e2dbe", + "reference": "136b19dd05cdf0709db6537d058bcab6dd6e2dbe", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-06-27T16:58:25+00:00" + } + ], "packages-dev": [ { "name": "doctrine/instantiator", @@ -1902,5 +2413,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.3.0" } diff --git a/readme.md b/readme.md index 525b60d..58140f1 100644 --- a/readme.md +++ b/readme.md @@ -61,7 +61,9 @@ Array //For payment verification use below method. You will then get below json as response. -echo $config->verifyPayment($response['payment_ref_id']); +$helper = new Helper($config); +$response = $helper->verifyPayment($response['payment_ref_id']); + ## Payment verification Response { merchantId: "683XXXX225", diff --git a/src/Exception/ExceptionHandler.php b/src/Exception/ExceptionHandler.php index f4068b5..d8e0bf0 100644 --- a/src/Exception/ExceptionHandler.php +++ b/src/Exception/ExceptionHandler.php @@ -18,7 +18,7 @@ public function __construct($message = "", $code = 0, Throwable $previous = null * Generate Custom Exception * @return array */ - public function generateException() + public function generateException(): array { return [ 'error' => 'error', diff --git a/src/Exception/NagadPaymentException.php b/src/Exception/NagadPaymentException.php new file mode 100644 index 0000000..4fee04a --- /dev/null +++ b/src/Exception/NagadPaymentException.php @@ -0,0 +1,31 @@ + 'error', + 'message' => $this->getMessage(), + 'line' => $this->getLine(), + 'file' => $this->getFile() + ]; + + } +} \ No newline at end of file diff --git a/src/Helper.php b/src/Helper.php index 7b75de4..730160e 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -13,12 +13,16 @@ namespace Xenon\NagadApi; +use Exception; use GuzzleHttp\Exception\GuzzleException; use Xenon\NagadApi\Exception\ExceptionHandler; +use Xenon\NagadApi\Exception\NagadPaymentException; use Xenon\NagadApi\lib\Key; class Helper extends Key { + + /** * Helper constructor. * @param $config @@ -26,6 +30,7 @@ class Helper extends Key */ public function __construct($config) { + parent::__construct($config); } @@ -37,7 +42,7 @@ public function __construct($config) * @return string * @since v1.3.1 */ - public static function generateRandomString($length = 40, $prefix = '', $suffix = '') + public static function generateRandomString(int $length = 40, string $prefix = '', string $suffix = '') { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); @@ -70,9 +75,9 @@ function EncryptDataWithPublicKey($data) $status = openssl_public_encrypt($data, $cryptoText, $keyResource); if ($status) { return base64_encode($cryptoText); - } else { - throw new ExceptionHandler('Invalid Public key'); } + + throw new ExceptionHandler('Invalid Public key'); } /** @@ -89,18 +94,15 @@ public function SignatureGenerate($data) if ($status) { return base64_encode($signature); - } else { - throw new ExceptionHandler('Invalid private key'); } - } + throw new ExceptionHandler('Invalid private key'); + } /** - * HTTP Post Method Request * @param $PostURL * @param $PostData - * @return mixed - * @throws GuzzleException + * @return array|mixed * @since v1.3.1 */ public function HttpPostMethod($PostURL, $PostData) @@ -129,12 +131,12 @@ public function HttpPostMethod($PostURL, $PostData) return [ 'error' => $curl_error ]; - } else { - $response = json_decode($resultData, true, 512); - curl_close($url); - return $response; } + $response = json_decode($resultData, true, 512); + curl_close($url); + return $response; + } @@ -142,6 +144,7 @@ public function HttpPostMethod($PostURL, $PostData) * Http Get Method * @param $url * @return bool|string + * @throws Exception */ public static function HttpGet($url) { @@ -154,9 +157,15 @@ public static function HttpGet($url) curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - $file_contents = curl_exec($ch); + + $response = curl_exec($ch); + if (curl_errno($ch)) { + $error_msg = curl_error($ch); + throw new NagadPaymentException($error_msg); + } + curl_close($ch); - return $file_contents; + return $response; } /** @@ -265,10 +274,26 @@ public static function serverDetails() */ public static function successResponse($response) { - // $response = 'https://phpdark.com/payment/success/id=4/?merchant=683002007104225&order_id=EBSXGJ5OYQCRO7D&payment_ref_id=MTEyOTAwMjY1NDMxNi42ODMwMDIwMDcxMDQyMjUuRUJTWEdKNU9ZUUNSTzdELmExODVkYWE4MDAyMDEyM2ZlYzRl&status=Success&status_code=00_0000_000&message=Successful%20Transaction&payment_dt=20201129002747&issuer_payment_ref=MTEyOTAwMjY1NDMxNi42ODMwMDIwMDcxMDQyMjUuRUJTWEdKNU9ZUUNSTzdELmExODVkYWE4MDAyMDEyM2ZlYzRl'; + // $response = 'https://example.com/payment/success/id=4/?merchant=683002007104225&order_id=EBSXGJ5OYQCRO7D&payment_ref_id=MTEyOTAwMjY1NDMxNi42ODMwMDIwMDcxMDQyMjUuRUJTWEdKNU9ZUUNSTzdELmExODVkYWE4MDAyMDEyM2ZlYzRl&status=Success&status_code=00_0000_000&message=Successful%20Transaction&payment_dt=20201129002747&issuer_payment_ref=MTEyOTAwMjY1NDMxNi42ODMwMDIwMDcxMDQyMjUuRUJTWEdKNU9ZUUNSTzdELmExODVkYWE4MDAyMDEyM2ZlYzRl'; $parts = parse_url($response); parse_str($parts['query'], $query); return $query; } + /** + * Verify Payment + * @throws Exception + */ + public function verifyPayment($paymentRefId) + { + $this->base_url = 'http://sandbox.mynagad.com:10080/remote-payment-gateway-1.0/api/dfs/'; + if ($this->getAppEnv() === 'production') { + $this->base_url = 'https://api.mynagad.com/api/dfs/'; + } + + $url = $this->base_url . 'verify/payment/' . $paymentRefId; + + return self::HttpGet($url); + } + } \ No newline at end of file diff --git a/src/RequestHandler.php b/src/RequestHandler.php index 5d7d51d..34ef96a 100644 --- a/src/RequestHandler.php +++ b/src/RequestHandler.php @@ -12,12 +12,13 @@ namespace Xenon\NagadApi; +use Carbon\Carbon; use Exception; use Xenon\NagadApi\Exception\ExceptionHandler; /** * This is the main performer that means request handler for entire nagadApi - * This class is doing extra-ordinary job according to request type. + * This class is doing extraordinary job according to request type. * It also generates api response for viewing in monitor screen. * Class RequestHandler * @package NagadApi @@ -188,7 +189,7 @@ private function showResponse($resultData, $sensitiveData, $postData) 'request' => [ 'environment' => $this->base->environment, 'time' => [ - 'request time' => date('Y-m-d H:i:s'), + 'request time' => Carbon::now(), 'timezone' => $this->base->getTimezone() ], 'url' => [ diff --git a/src/lib/Key.php b/src/lib/Key.php index 8dd7e99..a3be9d7 100644 --- a/src/lib/Key.php +++ b/src/lib/Key.php @@ -21,17 +21,36 @@ */ class Key { - private $appEnv; + /** + * @var mixed + */ + protected $appEnv; + /** + * @var mixed + */ private $appAccount; + /** + * @var mixed + */ private $appMerchantID; + /** + * @var mixed + */ private $merchantPrivateKey; + /** + * @var mixed + */ private $pgPublicKey; + /** + * @var string + */ private $currencyCode = '050'; + /** + * @var mixed|string + */ private $timeZone = 'Asia/Dhaka'; - //private $merchantID = ''; - /** * Key constructor. * @param $config @@ -59,9 +78,9 @@ public function __construct($config) $this->appMerchantID = $envData['NAGAD_APP_MERCHANTID']; $this->merchantPrivateKey = $envData['NAGAD_APP_MERCHANT_PRIVATE_KEY']; $this->pgPublicKey = $envData['NAGAD_APP_MERCHANT_PG_PUBLIC_KEY']; - if (array_key_exists('NAGAD_APP_TIMEZONE', $envData)) - + if (array_key_exists('NAGAD_APP_TIMEZONE', $envData)) { $this->timeZone = $envData['NAGAD_APP_TIMEZONE']; + } }