From 2b59c39c8c2a09330fbfb690e2bffbf3bec7fde9 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Tue, 12 Sep 2023 15:14:26 +0700 Subject: [PATCH 01/32] bump to php8 --- composer.json | 13 +++++++++---- tests/GatewayTest.php | 2 +- tests/Message/IncomingRequestTest.php | 2 +- tests/Message/PurchaseRequestTest.php | 2 +- tests/Message/QueryTransactionRequestTest.php | 2 +- tests/Message/RefundRequestTest.php | 2 +- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index f2e9dba..68da39b 100644 --- a/composer.json +++ b/composer.json @@ -19,11 +19,13 @@ } ], "require": { - "php": "^7.1", - "omnipay/common": "^3.0" + "php": "^7.1|8.*", + "omnipay/common": "^3.0", + "php-http/guzzle7-adapter": "^1.0" }, "require-dev": { - "omnipay/tests": "^3.0", + "http-interop/http-factory-guzzle": "^1.2", + "omnipay/tests": "^4.0", "scrutinizer/ocular": "^1.5" }, "autoload": { @@ -40,7 +42,10 @@ "test": "\"vendor/bin/phpunit\"" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "php-http/discovery": true + } }, "extra": { "branch-alias": { diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index c95b4d4..90054f2 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -26,7 +26,7 @@ class GatewayTest extends GatewayTestCase */ protected $gateway; - protected function setUp() + protected function setUp(): void { $this->gateway = Omnipay::create('VNPay', $this->getHttpClient(), $this->getHttpRequest()); $this->gateway->setVnpTmnCode('COCOSIN'); diff --git a/tests/Message/IncomingRequestTest.php b/tests/Message/IncomingRequestTest.php index 9f62816..53dc9fa 100644 --- a/tests/Message/IncomingRequestTest.php +++ b/tests/Message/IncomingRequestTest.php @@ -22,7 +22,7 @@ class IncomingRequestTest extends TestCase */ private $request; - public function setUp() + public function setUp(): void { $client = $this->getHttpClient(); $request = $this->getHttpRequest(); diff --git a/tests/Message/PurchaseRequestTest.php b/tests/Message/PurchaseRequestTest.php index b36520c..74b8ed7 100644 --- a/tests/Message/PurchaseRequestTest.php +++ b/tests/Message/PurchaseRequestTest.php @@ -22,7 +22,7 @@ class PurchaseRequestTest extends TestCase */ private $request; - public function setUp() + public function setUp(): void { $client = $this->getHttpClient(); $request = $this->getHttpRequest(); diff --git a/tests/Message/QueryTransactionRequestTest.php b/tests/Message/QueryTransactionRequestTest.php index 808b44e..730978f 100644 --- a/tests/Message/QueryTransactionRequestTest.php +++ b/tests/Message/QueryTransactionRequestTest.php @@ -22,7 +22,7 @@ class QueryTransactionRequestTest extends TestCase */ private $request; - public function setUp() + public function setUp(): void { $client = $this->getHttpClient(); $request = $this->getHttpRequest(); diff --git a/tests/Message/RefundRequestTest.php b/tests/Message/RefundRequestTest.php index 6e12873..314343d 100644 --- a/tests/Message/RefundRequestTest.php +++ b/tests/Message/RefundRequestTest.php @@ -22,7 +22,7 @@ class RefundRequestTest extends TestCase */ private $request; - public function setUp() + public function setUp(): void { $client = $this->getHttpClient(); $request = $this->getHttpRequest(); From 9fb7f98b3822cd41410e2ffb907e07dea90c6c9d Mon Sep 17 00:00:00 2001 From: bangnokia Date: Tue, 12 Sep 2023 15:15:03 +0700 Subject: [PATCH 02/32] migrate phpunit.xml.dist to new version --- phpunit.xml.dist | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9af3c5d..4ec8536 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,22 +1,13 @@ - - - - tests - - - - - src/ - - + + + + src/ + + + + + tests + + From 33a0b6df8a6e903833f8d07b869042746d38e07e Mon Sep 17 00:00:00 2001 From: bangnokia Date: Tue, 12 Sep 2023 15:17:08 +0700 Subject: [PATCH 03/32] fix deprecated function signature --- composer.json | 2 +- src/Message/QueryTransactionRequest.php | 2 +- src/Message/RefundRequest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 68da39b..0230996 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ } ], "require": { - "php": "^7.1|8.*", + "php": "^7.1|^8", "omnipay/common": "^3.0", "php-http/guzzle7-adapter": "^1.0" }, diff --git a/src/Message/QueryTransactionRequest.php b/src/Message/QueryTransactionRequest.php index 897f09c..7f7280f 100644 --- a/src/Message/QueryTransactionRequest.php +++ b/src/Message/QueryTransactionRequest.php @@ -42,7 +42,7 @@ public function initialize(array $parameters = []) */ public function sendData($data): SignatureResponse { - $query = http_build_query($data, null, '&', PHP_QUERY_RFC3986); + $query = http_build_query($data, '', '&', PHP_QUERY_RFC3986); $requestUrl = $this->getEndpoint().'?'.$query; $response = $this->httpClient->request('GET', $requestUrl); $responseRawData = $response->getBody()->getContents(); diff --git a/src/Message/RefundRequest.php b/src/Message/RefundRequest.php index d32669b..7688148 100644 --- a/src/Message/RefundRequest.php +++ b/src/Message/RefundRequest.php @@ -42,7 +42,7 @@ public function initialize(array $parameters = []) */ public function sendData($data): SignatureResponse { - $query = http_build_query($data, null, '&', PHP_QUERY_RFC3986); + $query = http_build_query($data, '', '&', PHP_QUERY_RFC3986); $requestUrl = $this->getEndpoint().'?'.$query; $response = $this->httpClient->request('GET', $requestUrl); $responseRawData = $response->getBody()->getContents(); From a23fe869bc49c2e90f8bce409123c45dd97e9f05 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Tue, 12 Sep 2023 15:58:52 +0700 Subject: [PATCH 04/32] bump default version --- src/Gateway.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gateway.php b/src/Gateway.php index 16acfd4..113403f 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -47,7 +47,7 @@ public function initialize(array $parameters = []) public function getDefaultParameters() { return [ - 'vnp_Version' => '2.0.0', + 'vnp_Version' => '2.1.0', ]; } From 4447bb382d35b4e5018d4626ef2e259098064531 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Tue, 12 Sep 2023 18:16:58 +0700 Subject: [PATCH 05/32] remove old signature version --- src/Message/Concerns/RequestSignature.php | 2 +- src/Support/Signature.php | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Message/Concerns/RequestSignature.php b/src/Message/Concerns/RequestSignature.php index c2357b9..1e36037 100644 --- a/src/Message/Concerns/RequestSignature.php +++ b/src/Message/Concerns/RequestSignature.php @@ -21,7 +21,7 @@ trait RequestSignature * @param string $hashType * @return string */ - protected function generateSignature(string $hashType = 'sha256'): string + protected function generateSignature(string $hashType = 'sha512'): string { $data = []; $signature = new Signature( diff --git a/src/Support/Signature.php b/src/Support/Signature.php index feb6074..0ebd3e9 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -36,7 +36,7 @@ class Signature * @param string $hashType * @throws InvalidArgumentException */ - public function __construct(string $hashSecret, string $hashType = 'sha256') + public function __construct(string $hashSecret, string $hashType = 'sha512') { if (! $this->isSupportHashType($hashType)) { throw new InvalidArgumentException(sprintf('Hash type: `%s` is not supported by VNPay', $hashType)); @@ -55,9 +55,8 @@ public function __construct(string $hashSecret, string $hashType = 'sha256') public function generate(array $data): string { ksort($data); - $dataSign = $this->hashSecret.urldecode(http_build_query($data)); - return hash($this->hashType, $dataSign); + return hash_hmac('sha512', http_build_query($data), $this->hashSecret); } /** @@ -82,6 +81,6 @@ public function validate(array $data, string $expect): bool */ protected function isSupportHashType(string $type): bool { - return 0 === strcasecmp($type, 'md5') || 0 === strcasecmp($type, 'sha256'); + return 0 === strcasecmp($type, 'sha512'); } } From 5fad3612ea8a53d9ee63638787a64fee38bcc014 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Tue, 12 Sep 2023 18:19:09 +0700 Subject: [PATCH 06/32] add vnp_ExpireDate --- src/Message/AbstractSignatureRequest.php | 17 ++++++++++++++--- src/Message/PurchaseRequest.php | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Message/AbstractSignatureRequest.php b/src/Message/AbstractSignatureRequest.php index 4b45a6c..4c04e56 100644 --- a/src/Message/AbstractSignatureRequest.php +++ b/src/Message/AbstractSignatureRequest.php @@ -37,6 +37,9 @@ public function initialize(array $parameters = []) $this->setVnpCreateDate( $this->getVnpCreateDate() ?? date('Ymdhis') ); + $this->setVnpExpireDate( + $this->getVnpExpireDate() ?? date('Ymdhis', strtotime('+15 minutes')) + ); return $this; } @@ -52,9 +55,7 @@ public function getData(): array ); $parameters = $this->getParameters(); - $parameters['vnp_SecureHash'] = $this->generateSignature( - $parameters['vnp_SecureHashType'] = $this->getSecureHashType() ?? 'sha256' - ); + $parameters['vnp_SecureHash'] = $this->generateSignature(); unset($parameters['vnp_HashSecret'], $parameters['testMode']); @@ -148,6 +149,16 @@ public function setVnpCreateDate(?string $date) return $this->setParameter('vnp_CreateDate', $date); } + public function getVnpExpireDate(): ?string + { + return $this->getParameter('vnp_ExpireDate'); + } + + public function setVnpExpireDate(string $date) + { + $this->setParameter('vnp_ExpireDate', $date); + } + /** * Trả về ip của khách dùng để thanh toán. * Đây là phương thức ánh xạ của [[getClientIp()]]. diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php index 7159a15..d333d8f 100644 --- a/src/Message/PurchaseRequest.php +++ b/src/Message/PurchaseRequest.php @@ -248,7 +248,7 @@ public function setReturnUrl($value) protected function getSignatureParameters(): array { $parameters = [ - 'vnp_CreateDate', 'vnp_IpAddr', 'vnp_ReturnUrl', 'vnp_Amount', 'vnp_OrderType', 'vnp_OrderInfo', + 'vnp_CreateDate', 'vnp_ExpireDate', 'vnp_IpAddr', 'vnp_ReturnUrl', 'vnp_Amount', 'vnp_OrderType', 'vnp_OrderInfo', 'vnp_TxnRef', 'vnp_CurrCode', 'vnp_Locale', 'vnp_TmnCode', 'vnp_Command', 'vnp_Version', ]; From c2a798ed91d3f0ab30431d92363c8f4c3bf030c7 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 01:36:49 +0700 Subject: [PATCH 07/32] remove weak hash algorithm --- src/Message/Concerns/RequestSignature.php | 5 +--- .../Concerns/ResponseSignatureValidation.php | 5 +--- src/Support/Signature.php | 25 +------------------ tests/GatewayTest.php | 7 +++--- 4 files changed, 7 insertions(+), 35 deletions(-) diff --git a/src/Message/Concerns/RequestSignature.php b/src/Message/Concerns/RequestSignature.php index 1e36037..bbde895 100644 --- a/src/Message/Concerns/RequestSignature.php +++ b/src/Message/Concerns/RequestSignature.php @@ -24,10 +24,7 @@ trait RequestSignature protected function generateSignature(string $hashType = 'sha512'): string { $data = []; - $signature = new Signature( - $this->getVnpHashSecret(), - $hashType - ); + $signature = new Signature($this->getVnpHashSecret()); foreach ($this->getSignatureParameters() as $parameter) { $data[$parameter] = $this->getParameter($parameter); diff --git a/src/Message/Concerns/ResponseSignatureValidation.php b/src/Message/Concerns/ResponseSignatureValidation.php index e6ae59c..52fd053 100644 --- a/src/Message/Concerns/ResponseSignatureValidation.php +++ b/src/Message/Concerns/ResponseSignatureValidation.php @@ -35,10 +35,7 @@ protected function validateSignature(): void && 'vnp_SecureHashType' !== $parameter; }, ARRAY_FILTER_USE_KEY); - $signature = new Signature( - $this->getRequest()->getVnpHashSecret(), - $data['vnp_SecureHashType'] ?? 'md5' - ); + $signature = new Signature($this->getRequest()->getVnpHashSecret()); if (! $signature->validate($dataSignature, $data['vnp_SecureHash'])) { throw new InvalidResponseException(sprintf('Data signature response from VNPay is invalid!')); diff --git a/src/Support/Signature.php b/src/Support/Signature.php index 0ebd3e9..c0ec13f 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -22,13 +22,6 @@ class Signature */ protected $hashSecret; - /** - * Loại thuật toán mã hóa sẽ sử dụng. - * - * @var string - */ - protected $hashType; - /** * Khởi tạo đối tượng DataSignature. * @@ -36,13 +29,8 @@ class Signature * @param string $hashType * @throws InvalidArgumentException */ - public function __construct(string $hashSecret, string $hashType = 'sha512') + public function __construct(string $hashSecret) { - if (! $this->isSupportHashType($hashType)) { - throw new InvalidArgumentException(sprintf('Hash type: `%s` is not supported by VNPay', $hashType)); - } - - $this->hashType = $hashType; $this->hashSecret = $hashSecret; } @@ -72,15 +60,4 @@ public function validate(array $data, string $expect): bool return 0 === strcasecmp($expect, $actual); } - - /** - * Phương thức cho biết loại mã hóa truyền vào có được VNPay hổ trợ hay không. - * - * @param string $type - * @return bool - */ - protected function isSupportHashType(string $type): bool - { - return 0 === strcasecmp($type, 'sha512'); - } } diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index 90054f2..077ea21 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -14,6 +14,7 @@ use Omnipay\Omnipay; use Omnipay\Tests\GatewayTestCase; use Omnipay\VNPay\Message\PurchaseResponse; +use Omnipay\VNPay\Support\Signature; /** * @author Vuong Minh @@ -80,12 +81,12 @@ public function testIncomingSuccess(string $requestMethod) 'vnp_OrderInfo' => 'Thanh+toan+don+hang+thoi+gian%3A+2017-08-29+15%3A27%3A02', 'vnp_PayDate' => 20170829153052, 'vnp_ResponseCode' => '00', - 'vnp_TmnCode' => '2QXUI4J4', + 'vnp_TmnCode' => 'COCOSIN', 'vnp_TransactionNo' => 12996460, 'vnp_TxnRef' => 23597, - 'vnp_SecureHash' => '32c2be7c9a4282ca13ce4a5e443902fe', - 'vnp_SecureHashType' => 'md5', + 'vnp_SecureHash' => 'f0de0729898a035116feb908a36a55fad7e9c7ebb5ded3e752a1dad891e6af2bbdd6f56505b6664bfc417422dae11c8813576f209e62c10f4919f7db5d37124f', ]); + $response = call_user_func([$this->gateway, $requestMethod])->send(); $this->assertTrue($response->isSuccessful()); From 3c977f8647b8a6dd44dd777cb565c91f9b30a894 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 01:53:31 +0700 Subject: [PATCH 08/32] wip --- tests/Message/PurchaseRequestTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Message/PurchaseRequestTest.php b/tests/Message/PurchaseRequestTest.php index 74b8ed7..9b1326d 100644 --- a/tests/Message/PurchaseRequestTest.php +++ b/tests/Message/PurchaseRequestTest.php @@ -44,7 +44,7 @@ public function testGetData() $request->setVnpReturnUrl(10); $request->setVnpTxnRef(11); $request->setVnpVersion(12); - $request->setSecureHashType('sha256'); + $request->setVnpExpireDate(13); $request->setTestMode(true); $data = $request->getData(); $this->assertEquals(14, count($data)); @@ -71,7 +71,7 @@ public function testGetData() $this->assertEquals(10, $data['vnp_ReturnUrl']); $this->assertEquals(11, $data['vnp_TxnRef']); $this->assertEquals(12, $data['vnp_Version']); - $this->assertEquals('sha256', $data['vnp_SecureHashType']); + $this->assertEquals(13, $data['vnp_ExpireDate']); $this->assertTrue(isset($data['vnp_SecureHash'])); $this->assertFalse(isset($data['vnp_HashSecret'])); } From 6148ab7bf175e7e05e95f1c6ab1466219e7da5f4 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 02:00:05 +0700 Subject: [PATCH 09/32] update tests --- src/Support/Signature.php | 1 - tests/GatewayTest.php | 16 ++++++++++++++++ tests/Message/SignatureResponseTest.php | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Support/Signature.php b/src/Support/Signature.php index c0ec13f..37182b7 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -26,7 +26,6 @@ class Signature * Khởi tạo đối tượng DataSignature. * * @param string $hashSecret - * @param string $hashType * @throws InvalidArgumentException */ public function __construct(string $hashSecret) diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index 077ea21..02b5b62 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -19,6 +19,10 @@ /** * @author Vuong Minh * @since 1.0.0 + * + * @runTestsInSeparateProcesses + * @runInSeparateProcess + * @preserveGlobalState disabled */ class GatewayTest extends GatewayTestCase { @@ -117,6 +121,10 @@ public function testIncomingFailure(string $requestMethod) public function testQueryTransactionSuccess() { $this->setMockHttpResponse('QueryTransactionSuccess.txt'); + mock('overload:'.Signature::class, [ + 'validate' => true, + 'generate' => 'foobar' + ])->makePartial(); $response = $this->gateway->queryTransaction([ 'vnp_TransDate' => 20190705151126, 'vnp_TxnRef' => 1562314234, @@ -134,6 +142,10 @@ public function testQueryTransactionSuccess() public function testQueryTransactionFailure() { $this->setMockHttpResponse('QueryTransactionFailure.txt'); + mock('overload:'.Signature::class, [ + 'validate' => true, + 'generate' => 'foobar' + ])->makePartial(); $response = $this->gateway->queryTransaction([ 'vnp_TransDate' => 20190705151126, 'vnp_TxnRef' => 15623142234, @@ -149,6 +161,10 @@ public function testQueryTransactionFailure() public function testRefundSuccess() { $this->setMockHttpResponse('RefundSuccess.txt'); + mock('overload:'.Signature::class, [ + 'validate' => true, + 'generate' => 'foobar' + ])->makePartial(); $response = $this->gateway->refund([ 'vnp_Amount' => 10000, 'vnp_TransactionType' => '03', diff --git a/tests/Message/SignatureResponseTest.php b/tests/Message/SignatureResponseTest.php index 8972ffe..1d0277e 100644 --- a/tests/Message/SignatureResponseTest.php +++ b/tests/Message/SignatureResponseTest.php @@ -10,6 +10,7 @@ use Omnipay\Tests\TestCase; use Omnipay\VNPay\Message\SignatureResponse; +use Omnipay\VNPay\Support\Signature; /** * @author Vuong Minh @@ -41,8 +42,7 @@ public function testIncoming() 'vnp_TmnCode' => '2QXUI4J4', 'vnp_TransactionNo' => 12996460, 'vnp_TxnRef' => 23597, - 'vnp_SecureHash' => '32c2be7c9a4282ca13ce4a5e443902fe', - 'vnp_SecureHashType' => 'md5', + 'vnp_SecureHash' => 'c9acf5dc3da383d6f415bee855e5286c53f3b75da755b32328db74f0509fcaa9d874189a91f4f3fbb5d5ed90fc3f34176f8f103401105f5e9406b0b1a6bc3b2f', ]); $this->assertFalse($response->isPending()); $this->assertTrue($response->isSuccessful()); From 35e25e05eb5216986f82f676774536313c190777 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:26:52 +0700 Subject: [PATCH 10/32] try to test Signature --- src/Message/AbstractSignatureRequest.php | 18 ++++++------- src/Message/Concerns/RequestSignature.php | 3 ++- src/Support/Signature.php | 13 +++++++++- tests/GatewayTest.php | 31 +++++++++++------------ tests/Message/PurchaseRequestTest.php | 1 + 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/Message/AbstractSignatureRequest.php b/src/Message/AbstractSignatureRequest.php index 4c04e56..d7d3576 100644 --- a/src/Message/AbstractSignatureRequest.php +++ b/src/Message/AbstractSignatureRequest.php @@ -7,6 +7,7 @@ namespace Omnipay\VNPay\Message; +use Omnipay\Common\Exception\InvalidRequestException; use Omnipay\Common\Message\AbstractRequest; use Omnipay\VNPay\Concerns\Parameters; use Omnipay\VNPay\Concerns\ParametersNormalization; @@ -46,13 +47,12 @@ public function initialize(array $parameters = []) /** * {@inheritdoc} + * @throws InvalidRequestException */ public function getData(): array { - call_user_func_array( - [$this, 'validate'], - $this->getSignatureParameters() - ); + // refactor code above without call_user_func_array + $this->validate(...$this->getSignatureParameters()); $parameters = $this->getParameters(); $parameters['vnp_SecureHash'] = $this->generateSignature(); @@ -78,7 +78,7 @@ public function getVnpTxnRef(): ?string * Thiết lập mã đơn hàng cần thực thi tác vụ. * Đây là phương thức ánh xạ của [[setTransactionId()]]. * - * @param null|string $ref + * @param null|string $ref * * @return $this * @see setTransactionId @@ -117,7 +117,7 @@ public function getVnpOrderInfo(): ?string /** * Thiết lập thông tin đơn hàng hay lý do truy vấn đến VNPay. * - * @param null|string $info + * @param null|string $info * @return $this */ public function setVnpOrderInfo(?string $info) @@ -140,7 +140,7 @@ public function getVnpCreateDate(): ?string * Thiết lập thời gian khởi tạo truy vấn đến VNPay. * Mặc định sẽ là thời gian hiện tại. * - * @param null|string $date + * @param null|string $date * @return $this * @see setReturnUrl */ @@ -176,7 +176,7 @@ public function getVnpIpAddr(): ?string * Đây là phương thức ánh xạ của [[setClientIp()]]. * Mặc định nếu không thiết lập sẽ là IP của khách. * - * @param null|string $ip + * @param null|string $ip * @return $this * @see setClientIp */ @@ -215,7 +215,7 @@ public function getSecureHashType(): ?string /** * Thiết lập phương thức mã hóa dùng để tạo chữ ký dự liệu. * - * @param null|string $secureHashType + * @param null|string $secureHashType * * @return $this * @since 1.0.1 diff --git a/src/Message/Concerns/RequestSignature.php b/src/Message/Concerns/RequestSignature.php index bbde895..14f8ac8 100644 --- a/src/Message/Concerns/RequestSignature.php +++ b/src/Message/Concerns/RequestSignature.php @@ -24,12 +24,13 @@ trait RequestSignature protected function generateSignature(string $hashType = 'sha512'): string { $data = []; - $signature = new Signature($this->getVnpHashSecret()); foreach ($this->getSignatureParameters() as $parameter) { $data[$parameter] = $this->getParameter($parameter); } + $signature = new Signature($this->getVnpHashSecret()); + return $signature->generate($data); } diff --git a/src/Support/Signature.php b/src/Support/Signature.php index 37182b7..6258d19 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -22,13 +22,15 @@ class Signature */ protected $hashSecret; + public static $restResult; + /** * Khởi tạo đối tượng DataSignature. * * @param string $hashSecret * @throws InvalidArgumentException */ - public function __construct(string $hashSecret) + public function __construct(string $hashSecret = '') { $this->hashSecret = $hashSecret; } @@ -55,8 +57,17 @@ public function generate(array $data): string */ public function validate(array $data, string $expect): bool { + if (static::$restResult !== null) { + return true; + } + $actual = $this->generate($data); return 0 === strcasecmp($expect, $actual); } + + public static function setTestValidateResult($result) + { + static::$restResult = $result; + } } diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index 02b5b62..facc142 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -19,10 +19,6 @@ /** * @author Vuong Minh * @since 1.0.0 - * - * @runTestsInSeparateProcesses - * @runInSeparateProcess - * @preserveGlobalState disabled */ class GatewayTest extends GatewayTestCase { @@ -39,8 +35,16 @@ protected function setUp(): void $this->gateway->setTestMode(true); } + protected function tearDown(): void + { + parent::tearDown(); // TODO: Change the autogenerated stub + Signature::setTestValidateResult(null); + } + public function testPurchaseSuccess() { + Signature::setTestValidateResult(true); + $response = $this->gateway->purchase([ 'vnp_TxnRef' => time(), 'vnp_OrderType' => 100000, @@ -121,10 +125,8 @@ public function testIncomingFailure(string $requestMethod) public function testQueryTransactionSuccess() { $this->setMockHttpResponse('QueryTransactionSuccess.txt'); - mock('overload:'.Signature::class, [ - 'validate' => true, - 'generate' => 'foobar' - ])->makePartial(); + Signature::setTestValidateResult(true); + $response = $this->gateway->queryTransaction([ 'vnp_TransDate' => 20190705151126, 'vnp_TxnRef' => 1562314234, @@ -142,10 +144,8 @@ public function testQueryTransactionSuccess() public function testQueryTransactionFailure() { $this->setMockHttpResponse('QueryTransactionFailure.txt'); - mock('overload:'.Signature::class, [ - 'validate' => true, - 'generate' => 'foobar' - ])->makePartial(); + Signature::setTestValidateResult(true); + $response = $this->gateway->queryTransaction([ 'vnp_TransDate' => 20190705151126, 'vnp_TxnRef' => 15623142234, @@ -161,10 +161,8 @@ public function testQueryTransactionFailure() public function testRefundSuccess() { $this->setMockHttpResponse('RefundSuccess.txt'); - mock('overload:'.Signature::class, [ - 'validate' => true, - 'generate' => 'foobar' - ])->makePartial(); + Signature::setTestValidateResult(true); + $response = $this->gateway->refund([ 'vnp_Amount' => 10000, 'vnp_TransactionType' => '03', @@ -182,6 +180,7 @@ public function testRefundSuccess() public function testRefundFailure() { $this->setMockHttpResponse('RefundFailure.txt'); + $response = $this->gateway->refund([ 'vnp_TxnRef' => 23597, 'vnp_Amount' => 10000, diff --git a/tests/Message/PurchaseRequestTest.php b/tests/Message/PurchaseRequestTest.php index 9b1326d..b13e74d 100644 --- a/tests/Message/PurchaseRequestTest.php +++ b/tests/Message/PurchaseRequestTest.php @@ -27,6 +27,7 @@ public function setUp(): void $client = $this->getHttpClient(); $request = $this->getHttpRequest(); $this->request = new PurchaseRequest($client, $request); + $this->request->initialize(); } public function testGetData() From 02706fabadd486ef4cd84b939575533b8cb3912d Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:30:27 +0700 Subject: [PATCH 11/32] cleanup --- src/Message/Concerns/ResponseSignatureValidation.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Message/Concerns/ResponseSignatureValidation.php b/src/Message/Concerns/ResponseSignatureValidation.php index 52fd053..23731b6 100644 --- a/src/Message/Concerns/ResponseSignatureValidation.php +++ b/src/Message/Concerns/ResponseSignatureValidation.php @@ -30,9 +30,7 @@ protected function validateSignature(): void } $dataSignature = array_filter($this->getData(), function ($parameter) { - return 0 === strpos($parameter, 'vnp_') - && 'vnp_SecureHash' !== $parameter - && 'vnp_SecureHashType' !== $parameter; + return 0 === strpos($parameter, 'vnp_') && 'vnp_SecureHash' !== $parameter; }, ARRAY_FILTER_USE_KEY); $signature = new Signature($this->getRequest()->getVnpHashSecret()); From d60733d7eaf9a355810219b57812f94ea8f4e7e1 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:30:41 +0700 Subject: [PATCH 12/32] cleanup --- src/Message/Concerns/ResponseSignatureValidation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Message/Concerns/ResponseSignatureValidation.php b/src/Message/Concerns/ResponseSignatureValidation.php index 23731b6..4348fcd 100644 --- a/src/Message/Concerns/ResponseSignatureValidation.php +++ b/src/Message/Concerns/ResponseSignatureValidation.php @@ -36,7 +36,7 @@ protected function validateSignature(): void $signature = new Signature($this->getRequest()->getVnpHashSecret()); if (! $signature->validate($dataSignature, $data['vnp_SecureHash'])) { - throw new InvalidResponseException(sprintf('Data signature response from VNPay is invalid!')); + throw new InvalidResponseException('Data signature response from VNPay is invalid!'); } } } From dff754900a07aae841867e7c31c04ee6eef40162 Mon Sep 17 00:00:00 2001 From: Nguyen Viet Date: Wed, 13 Sep 2023 03:38:24 +0700 Subject: [PATCH 13/32] add test action --- .github/workflows/run-tests.yml | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/run-tests.yml diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..7cb85a0 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,39 @@ +name: PHP Composer + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: [7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2] + + steps: + - uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: mbstring, pcntl, iconv + coverage: none + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Run test suite + run: composer run-script test From 4c97a5514edc820420533393badd1c9e29f90aab Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:39:26 +0700 Subject: [PATCH 14/32] wip --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 7cb85a0..73183da 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -20,7 +20,7 @@ jobs: php: [7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup PHP uses: shivammathur/setup-php@v2 From 3aa7fa6f8e4b3ebd6ec9b9a430779c0cd16f6896 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:40:43 +0700 Subject: [PATCH 15/32] drop php < 7.4 --- .github/workflows/run-tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 73183da..bf886ce 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - php: [7.1, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2] + php: [7.4, 8.0, 8.1, 8.2] steps: - uses: actions/checkout@v3 diff --git a/composer.json b/composer.json index 0230996..d0ebca6 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ } ], "require": { - "php": "^7.1|^8", + "php": "^7.4|^8", "omnipay/common": "^3.0", "php-http/guzzle7-adapter": "^1.0" }, From f76000af1eb487bc433a37cb14f2da680dd9f671 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:42:26 +0700 Subject: [PATCH 16/32] rename branch --- .github/workflows/run-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index bf886ce..3ba66e4 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -2,9 +2,9 @@ name: PHP Composer on: push: - branches: [ "master" ] + branches: [ "main" ] pull_request: - branches: [ "master" ] + branches: [ "main" ] permissions: contents: read From f0ca18fed0fcf4a7e93d41c3362e71a6f9233dd9 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:46:03 +0700 Subject: [PATCH 17/32] wip --- .github/workflows/run-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 3ba66e4..b5c1421 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -26,7 +26,6 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - extensions: mbstring, pcntl, iconv coverage: none - name: Validate composer.json and composer.lock From 7806fa63a0379fab877125ba3d3dcf9ed949dfcf Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 03:52:00 +0700 Subject: [PATCH 18/32] revert construct signature --- src/Support/Signature.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Support/Signature.php b/src/Support/Signature.php index 6258d19..ae1a30c 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -30,7 +30,7 @@ class Signature * @param string $hashSecret * @throws InvalidArgumentException */ - public function __construct(string $hashSecret = '') + public function __construct(string $hashSecret) { $this->hashSecret = $hashSecret; } From 07b796b670c3ec3d419c97b1f9e585c68b1d3bfc Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 04:26:08 +0700 Subject: [PATCH 19/32] wip --- src/Message/Concerns/RequestSignature.php | 2 +- .../Concerns/ResponseSignatureValidation.php | 4 +- src/Support/Signature.php | 34 +++-- tests/GatewayTest.php | 120 ++++++++++-------- tests/Message/SignatureResponseTest.php | 5 + tests/Mock/SignatureMock.php | 18 +++ 6 files changed, 110 insertions(+), 73 deletions(-) create mode 100644 tests/Mock/SignatureMock.php diff --git a/src/Message/Concerns/RequestSignature.php b/src/Message/Concerns/RequestSignature.php index 14f8ac8..a9efe70 100644 --- a/src/Message/Concerns/RequestSignature.php +++ b/src/Message/Concerns/RequestSignature.php @@ -29,7 +29,7 @@ protected function generateSignature(string $hashType = 'sha512'): string $data[$parameter] = $this->getParameter($parameter); } - $signature = new Signature($this->getVnpHashSecret()); + $signature = Signature::make($this->getVnpHashSecret()); return $signature->generate($data); } diff --git a/src/Message/Concerns/ResponseSignatureValidation.php b/src/Message/Concerns/ResponseSignatureValidation.php index 4348fcd..6ed6306 100644 --- a/src/Message/Concerns/ResponseSignatureValidation.php +++ b/src/Message/Concerns/ResponseSignatureValidation.php @@ -30,10 +30,10 @@ protected function validateSignature(): void } $dataSignature = array_filter($this->getData(), function ($parameter) { - return 0 === strpos($parameter, 'vnp_') && 'vnp_SecureHash' !== $parameter; + return 0 === strpos($parameter, 'vnp_') && $parameter !== 'vnp_SecureHash'; }, ARRAY_FILTER_USE_KEY); - $signature = new Signature($this->getRequest()->getVnpHashSecret()); + $signature = Signature::make($this->getRequest()->getVnpHashSecret()); if (! $signature->validate($dataSignature, $data['vnp_SecureHash'])) { throw new InvalidResponseException('Data signature response from VNPay is invalid!'); diff --git a/src/Support/Signature.php b/src/Support/Signature.php index ae1a30c..dfa80a4 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -17,12 +17,10 @@ class Signature { /** * Khóa bí mật dùng để tạo và kiểm tra chữ ký dữ liệu. - * - * @var string */ - protected $hashSecret; + protected string $hashSecret; - public static $restResult; + protected static ?Signature $instance = null; /** * Khởi tạo đối tượng DataSignature. @@ -30,11 +28,28 @@ class Signature * @param string $hashSecret * @throws InvalidArgumentException */ - public function __construct(string $hashSecret) + private function __construct(string $hashSecret) { $this->hashSecret = $hashSecret; } + /** + * Tạo đối tượng singleton. + */ + public static function make(string $hashSecret): Signature + { + if (static::$instance === null) { + static::$instance = new static($hashSecret); + } + + return static::$instance; + } + + public static function swap(?Signature $signature) + { + static::$instance = $signature; + } + /** * Trả về chữ ký dữ liệu của dữ liệu truyền vào. * @@ -57,17 +72,8 @@ public function generate(array $data): string */ public function validate(array $data, string $expect): bool { - if (static::$restResult !== null) { - return true; - } - $actual = $this->generate($data); return 0 === strcasecmp($expect, $actual); } - - public static function setTestValidateResult($result) - { - static::$restResult = $result; - } } diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index facc142..457c1e4 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -15,6 +15,7 @@ use Omnipay\Tests\GatewayTestCase; use Omnipay\VNPay\Message\PurchaseResponse; use Omnipay\VNPay\Support\Signature; +use Omnipay\VNPay\Tests\Mock\SignatureMock; /** * @author Vuong Minh @@ -27,30 +28,35 @@ class GatewayTest extends GatewayTestCase */ protected $gateway; + protected $mockSignature; + protected function setUp(): void { $this->gateway = Omnipay::create('VNPay', $this->getHttpClient(), $this->getHttpRequest()); $this->gateway->setVnpTmnCode('COCOSIN'); $this->gateway->setVnpHashSecret('RAOEXHYVSDDIIENYWSLDIIZTANXUXZFJ'); $this->gateway->setTestMode(true); + + $this->mockSignature = mock(SignatureMock::class)->makePartial(); } protected function tearDown(): void { - parent::tearDown(); // TODO: Change the autogenerated stub - Signature::setTestValidateResult(null); + parent::tearDown(); + Signature::swap(null); } public function testPurchaseSuccess() { - Signature::setTestValidateResult(true); + Signature::swap($this->mockSignature); + $this->mockSignature->shouldReceive('generate')->once(); $response = $this->gateway->purchase([ - 'vnp_TxnRef' => time(), + 'vnp_TxnRef' => time(), 'vnp_OrderType' => 100000, 'vnp_OrderInfo' => time(), - 'vnp_IpAddr' => '127.0.0.1', - 'vnp_Amount' => 1000000, + 'vnp_IpAddr' => '127.0.0.1', + 'vnp_Amount' => 1000000, 'vnp_ReturnUrl' => 'https://github.com/phpviet', ])->send(); @@ -66,11 +72,11 @@ public function testPurchaseFailure() { $this->expectException(InvalidRequestException::class); $this->gateway->purchase([ - 'vnp_TxnRef' => time(), + 'vnp_TxnRef' => time(), 'vnp_OrderType' => 100000, - 'OrderInfo' => time(), - 'vnp_IpAddr' => '127.0.0.1', - 'vnp_Amount' => 1000000, + 'OrderInfo' => time(), + 'vnp_IpAddr' => '127.0.0.1', + 'vnp_Amount' => 1000000, 'vnp_ReturnUrl' => 'https://github.com/phpviet', ])->send(); } @@ -82,17 +88,17 @@ public function testPurchaseFailure() public function testIncomingSuccess(string $requestMethod) { $this->getHttpRequest()->query->replace([ - 'vnp_Amount' => 1000000, - 'vnp_BankCode' => 'NCB', - 'vnp_BankTranNo' => 20170829152730, - 'vnp_CardType' => 'ATM', - 'vnp_OrderInfo' => 'Thanh+toan+don+hang+thoi+gian%3A+2017-08-29+15%3A27%3A02', - 'vnp_PayDate' => 20170829153052, - 'vnp_ResponseCode' => '00', - 'vnp_TmnCode' => 'COCOSIN', + 'vnp_Amount' => 1000000, + 'vnp_BankCode' => 'NCB', + 'vnp_BankTranNo' => 20170829152730, + 'vnp_CardType' => 'ATM', + 'vnp_OrderInfo' => 'Thanh+toan+don+hang+thoi+gian%3A+2017-08-29+15%3A27%3A02', + 'vnp_PayDate' => 20170829153052, + 'vnp_ResponseCode' => '00', + 'vnp_TmnCode' => 'COCOSIN', 'vnp_TransactionNo' => 12996460, - 'vnp_TxnRef' => 23597, - 'vnp_SecureHash' => 'f0de0729898a035116feb908a36a55fad7e9c7ebb5ded3e752a1dad891e6af2bbdd6f56505b6664bfc417422dae11c8813576f209e62c10f4919f7db5d37124f', + 'vnp_TxnRef' => 23597, + 'vnp_SecureHash' => 'f0de0729898a035116feb908a36a55fad7e9c7ebb5ded3e752a1dad891e6af2bbdd6f56505b6664bfc417422dae11c8813576f209e62c10f4919f7db5d37124f', ]); $response = call_user_func([$this->gateway, $requestMethod])->send(); @@ -112,9 +118,9 @@ public function testIncomingSuccess(string $requestMethod) public function testIncomingFailure(string $requestMethod) { $this->getHttpRequest()->query->replace([ - 'vnp_Amount' => 1000000, + 'vnp_Amount' => 1000000, 'vnp_ResponseCode' => '00', - 'vnp_SecureHash' => '32c2be7c9a4282ca13ce4a5e443902fe', + 'vnp_SecureHash' => '32c2be7c9a4282ca13ce4a5e443902fe', ]); $this->expectException(InvalidResponseException::class); @@ -125,13 +131,14 @@ public function testIncomingFailure(string $requestMethod) public function testQueryTransactionSuccess() { $this->setMockHttpResponse('QueryTransactionSuccess.txt'); - Signature::setTestValidateResult(true); + Signature::swap($this->mockSignature); + $this->mockSignature->shouldReceive('validate')->once()->andReturn(true); $response = $this->gateway->queryTransaction([ - 'vnp_TransDate' => 20190705151126, - 'vnp_TxnRef' => 1562314234, - 'vnp_OrderInfo' => time(), - 'vnp_IpAddr' => '127.0.0.1', + 'vnp_TransDate' => 20190705151126, + 'vnp_TxnRef' => 1562314234, + 'vnp_OrderInfo' => time(), + 'vnp_IpAddr' => '127.0.0.1', 'vnp_TransactionNo' => 496558, ])->send(); @@ -144,13 +151,13 @@ public function testQueryTransactionSuccess() public function testQueryTransactionFailure() { $this->setMockHttpResponse('QueryTransactionFailure.txt'); - Signature::setTestValidateResult(true); + Signature::swap($this->mockSignature); $response = $this->gateway->queryTransaction([ - 'vnp_TransDate' => 20190705151126, - 'vnp_TxnRef' => 15623142234, - 'vnp_OrderInfo' => time(), - 'vnp_IpAddr' => '127.0.0.1', + 'vnp_TransDate' => 20190705151126, + 'vnp_TxnRef' => 15623142234, + 'vnp_OrderInfo' => time(), + 'vnp_IpAddr' => '127.0.0.1', 'vnp_TransactionNo' => 4961111558, ])->send(); @@ -161,16 +168,17 @@ public function testQueryTransactionFailure() public function testRefundSuccess() { $this->setMockHttpResponse('RefundSuccess.txt'); - Signature::setTestValidateResult(true); + Signature::swap($this->mockSignature); + $this->mockSignature->shouldReceive('validate')->once()->andReturn(true); $response = $this->gateway->refund([ - 'vnp_Amount' => 10000, + 'vnp_Amount' => 10000, 'vnp_TransactionType' => '03', - 'vnp_TransDate' => 20190705151126, - 'vnp_TxnRef' => 32321, - 'vnp_OrderInfo' => time(), - 'vnp_IpAddr' => '127.0.0.1', - 'vnp_TransactionNo' => 496558, + 'vnp_TransDate' => 20190705151126, + 'vnp_TxnRef' => 32321, + 'vnp_OrderInfo' => time(), + 'vnp_IpAddr' => '127.0.0.1', + 'vnp_TransactionNo' => 496558, ])->send(); $this->assertTrue($response->isSuccessful()); @@ -182,12 +190,12 @@ public function testRefundFailure() $this->setMockHttpResponse('RefundFailure.txt'); $response = $this->gateway->refund([ - 'vnp_TxnRef' => 23597, - 'vnp_Amount' => 10000, + 'vnp_TxnRef' => 23597, + 'vnp_Amount' => 10000, 'vnp_TransactionType' => '03', - 'vnp_OrderInfo' => time(), - 'vnp_IpAddr' => '127.0.0.1', - 'vnp_TransDate' => 20190705151126, + 'vnp_OrderInfo' => time(), + 'vnp_IpAddr' => '127.0.0.1', + 'vnp_TransDate' => 20190705151126, ])->send(); $this->assertEquals(99, $response->getCode()); @@ -199,8 +207,8 @@ public function testDefaultParametersHaveMatchingMethods() $settings = $this->gateway->getDefaultParameters(); foreach ($settings as $key => $default) { $key = str_replace('_', '', $key); - $getter = 'get'.$key; - $setter = 'set'.$key; + $getter = 'get' . $key; + $setter = 'set' . $key; $value = uniqid(); $this->assertTrue(method_exists($this->gateway, $getter), "Gateway must implement $getter()"); @@ -214,8 +222,8 @@ public function testPurchaseParameters() { foreach ($this->gateway->getDefaultParameters() as $key => $default) { $key = str_replace('_', '', $key); - $getter = 'get'.$key; - $setter = 'set'.$key; + $getter = 'get' . $key; + $setter = 'set' . $key; $value = uniqid(); $this->gateway->$setter($value); @@ -229,8 +237,8 @@ public function testRefundParameters() { foreach ($this->gateway->getDefaultParameters() as $key => $default) { $key = str_replace('_', '', $key); - $getter = 'get'.$key; - $setter = 'set'.$key; + $getter = 'get' . $key; + $setter = 'set' . $key; $value = uniqid(); $this->gateway->$setter($value); @@ -244,8 +252,8 @@ public function testCompletePurchaseParameters() { foreach ($this->gateway->getDefaultParameters() as $key => $default) { $key = str_replace('_', '', $key); - $getter = 'get'.$key; - $setter = 'set'.$key; + $getter = 'get' . $key; + $setter = 'set' . $key; $value = uniqid(); $this->gateway->$setter($value); @@ -259,8 +267,8 @@ public function testQueryTransactionParameters() { foreach ($this->gateway->getDefaultParameters() as $key => $default) { $key = str_replace('_', '', $key); - $getter = 'get'.$key; - $setter = 'set'.$key; + $getter = 'get' . $key; + $setter = 'set' . $key; $value = uniqid(); $this->gateway->$setter($value); @@ -274,8 +282,8 @@ public function testNotificationParameters() { foreach ($this->gateway->getDefaultParameters() as $key => $default) { $key = str_replace('_', '', $key); - $getter = 'get'.$key; - $setter = 'set'.$key; + $getter = 'get' . $key; + $setter = 'set' . $key; $value = uniqid(); $this->gateway->$setter($value); diff --git a/tests/Message/SignatureResponseTest.php b/tests/Message/SignatureResponseTest.php index 1d0277e..e591f18 100644 --- a/tests/Message/SignatureResponseTest.php +++ b/tests/Message/SignatureResponseTest.php @@ -27,6 +27,11 @@ public function testConstruct() $this->assertEquals(['example' => 'value', 'foo' => 'bar'], $response->getData()); } + public function tearDown(): void + { + Signature::swap(null); // reset singleton + } + public function testIncoming() { $request = $this->getMockRequest(); diff --git a/tests/Mock/SignatureMock.php b/tests/Mock/SignatureMock.php new file mode 100644 index 0000000..d427962 --- /dev/null +++ b/tests/Mock/SignatureMock.php @@ -0,0 +1,18 @@ + Date: Wed, 13 Sep 2023 04:31:19 +0700 Subject: [PATCH 20/32] force create --- src/Support/Signature.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Support/Signature.php b/src/Support/Signature.php index dfa80a4..e42ec2b 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -36,9 +36,9 @@ private function __construct(string $hashSecret) /** * Tạo đối tượng singleton. */ - public static function make(string $hashSecret): Signature + public static function make(string $hashSecret, bool $forceCreate = false): Signature { - if (static::$instance === null) { + if (static::$instance === null || $forceCreate) { static::$instance = new static($hashSecret); } From 175e1bb3d6cc68c4bc31ccfa7f67c76522647dce Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 04:33:11 +0700 Subject: [PATCH 21/32] cleanup --- src/Message/AbstractSignatureRequest.php | 1 - src/Support/Signature.php | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Message/AbstractSignatureRequest.php b/src/Message/AbstractSignatureRequest.php index d7d3576..a44a4e9 100644 --- a/src/Message/AbstractSignatureRequest.php +++ b/src/Message/AbstractSignatureRequest.php @@ -51,7 +51,6 @@ public function initialize(array $parameters = []) */ public function getData(): array { - // refactor code above without call_user_func_array $this->validate(...$this->getSignatureParameters()); $parameters = $this->getParameters(); diff --git a/src/Support/Signature.php b/src/Support/Signature.php index e42ec2b..4f117c1 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -20,6 +20,9 @@ class Signature */ protected string $hashSecret; + /** + * Đối tượng singleton. + */ protected static ?Signature $instance = null; /** @@ -45,7 +48,10 @@ public static function make(string $hashSecret, bool $forceCreate = false): Sign return static::$instance; } - public static function swap(?Signature $signature) + /** + * Swap đối tượng singleton. + */ + public static function swap(?Signature $signature): void { static::$instance = $signature; } From 630fc7cdb6c3318e364af6165ea33a1aa0c52df1 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 05:21:23 +0700 Subject: [PATCH 22/32] refactoring --- src/Message/Concerns/RequestSignature.php | 2 +- .../Concerns/ResponseSignatureValidation.php | 2 +- src/Support/Signature.php | 27 +------------------ tests/GatewayTest.php | 20 -------------- tests/Message/SignatureResponseTest.php | 5 ---- tests/Mock/QueryTransactionSuccess.txt | 2 +- tests/Mock/RefundSuccess.txt | 2 +- tests/Mock/SignatureMock.php | 18 ------------- 8 files changed, 5 insertions(+), 73 deletions(-) delete mode 100644 tests/Mock/SignatureMock.php diff --git a/src/Message/Concerns/RequestSignature.php b/src/Message/Concerns/RequestSignature.php index a9efe70..14f8ac8 100644 --- a/src/Message/Concerns/RequestSignature.php +++ b/src/Message/Concerns/RequestSignature.php @@ -29,7 +29,7 @@ protected function generateSignature(string $hashType = 'sha512'): string $data[$parameter] = $this->getParameter($parameter); } - $signature = Signature::make($this->getVnpHashSecret()); + $signature = new Signature($this->getVnpHashSecret()); return $signature->generate($data); } diff --git a/src/Message/Concerns/ResponseSignatureValidation.php b/src/Message/Concerns/ResponseSignatureValidation.php index 6ed6306..0e504d7 100644 --- a/src/Message/Concerns/ResponseSignatureValidation.php +++ b/src/Message/Concerns/ResponseSignatureValidation.php @@ -33,7 +33,7 @@ protected function validateSignature(): void return 0 === strpos($parameter, 'vnp_') && $parameter !== 'vnp_SecureHash'; }, ARRAY_FILTER_USE_KEY); - $signature = Signature::make($this->getRequest()->getVnpHashSecret()); + $signature = new Signature($this->getRequest()->getVnpHashSecret()); if (! $signature->validate($dataSignature, $data['vnp_SecureHash'])) { throw new InvalidResponseException('Data signature response from VNPay is invalid!'); diff --git a/src/Support/Signature.php b/src/Support/Signature.php index 4f117c1..cc605a4 100644 --- a/src/Support/Signature.php +++ b/src/Support/Signature.php @@ -20,42 +20,17 @@ class Signature */ protected string $hashSecret; - /** - * Đối tượng singleton. - */ - protected static ?Signature $instance = null; - /** * Khởi tạo đối tượng DataSignature. * * @param string $hashSecret * @throws InvalidArgumentException */ - private function __construct(string $hashSecret) + public function __construct(string $hashSecret) { $this->hashSecret = $hashSecret; } - /** - * Tạo đối tượng singleton. - */ - public static function make(string $hashSecret, bool $forceCreate = false): Signature - { - if (static::$instance === null || $forceCreate) { - static::$instance = new static($hashSecret); - } - - return static::$instance; - } - - /** - * Swap đối tượng singleton. - */ - public static function swap(?Signature $signature): void - { - static::$instance = $signature; - } - /** * Trả về chữ ký dữ liệu của dữ liệu truyền vào. * diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php index 457c1e4..e6d8a60 100644 --- a/tests/GatewayTest.php +++ b/tests/GatewayTest.php @@ -14,8 +14,6 @@ use Omnipay\Omnipay; use Omnipay\Tests\GatewayTestCase; use Omnipay\VNPay\Message\PurchaseResponse; -use Omnipay\VNPay\Support\Signature; -use Omnipay\VNPay\Tests\Mock\SignatureMock; /** * @author Vuong Minh @@ -28,29 +26,16 @@ class GatewayTest extends GatewayTestCase */ protected $gateway; - protected $mockSignature; - protected function setUp(): void { $this->gateway = Omnipay::create('VNPay', $this->getHttpClient(), $this->getHttpRequest()); $this->gateway->setVnpTmnCode('COCOSIN'); $this->gateway->setVnpHashSecret('RAOEXHYVSDDIIENYWSLDIIZTANXUXZFJ'); $this->gateway->setTestMode(true); - - $this->mockSignature = mock(SignatureMock::class)->makePartial(); - } - - protected function tearDown(): void - { - parent::tearDown(); - Signature::swap(null); } public function testPurchaseSuccess() { - Signature::swap($this->mockSignature); - $this->mockSignature->shouldReceive('generate')->once(); - $response = $this->gateway->purchase([ 'vnp_TxnRef' => time(), 'vnp_OrderType' => 100000, @@ -131,8 +116,6 @@ public function testIncomingFailure(string $requestMethod) public function testQueryTransactionSuccess() { $this->setMockHttpResponse('QueryTransactionSuccess.txt'); - Signature::swap($this->mockSignature); - $this->mockSignature->shouldReceive('validate')->once()->andReturn(true); $response = $this->gateway->queryTransaction([ 'vnp_TransDate' => 20190705151126, @@ -151,7 +134,6 @@ public function testQueryTransactionSuccess() public function testQueryTransactionFailure() { $this->setMockHttpResponse('QueryTransactionFailure.txt'); - Signature::swap($this->mockSignature); $response = $this->gateway->queryTransaction([ 'vnp_TransDate' => 20190705151126, @@ -168,8 +150,6 @@ public function testQueryTransactionFailure() public function testRefundSuccess() { $this->setMockHttpResponse('RefundSuccess.txt'); - Signature::swap($this->mockSignature); - $this->mockSignature->shouldReceive('validate')->once()->andReturn(true); $response = $this->gateway->refund([ 'vnp_Amount' => 10000, diff --git a/tests/Message/SignatureResponseTest.php b/tests/Message/SignatureResponseTest.php index e591f18..1d0277e 100644 --- a/tests/Message/SignatureResponseTest.php +++ b/tests/Message/SignatureResponseTest.php @@ -27,11 +27,6 @@ public function testConstruct() $this->assertEquals(['example' => 'value', 'foo' => 'bar'], $response->getData()); } - public function tearDown(): void - { - Signature::swap(null); // reset singleton - } - public function testIncoming() { $request = $this->getMockRequest(); diff --git a/tests/Mock/QueryTransactionSuccess.txt b/tests/Mock/QueryTransactionSuccess.txt index 704898f..c5c125a 100644 --- a/tests/Mock/QueryTransactionSuccess.txt +++ b/tests/Mock/QueryTransactionSuccess.txt @@ -4,4 +4,4 @@ Server: Apache Connection: close Content-Type: text/plain; charset=utf-8 -vnp_Amount=1000000&vnp_Message=QueryDR+Success&vnp_OrderInfo=1562314234&vnp_PayDate=20190705151100&vnp_ResponseCode=00&vnp_TmnCode=COCOSIN&vnp_TransactionNo=496558&vnp_TransactionStatus=01&vnp_TxnRef=1562314234&vnp_SecureHash=8c3f728cef087916f1f7f2995106ec27 \ No newline at end of file +vnp_Amount=1000000&vnp_Message=QueryDR+Success&vnp_OrderInfo=1562314234&vnp_PayDate=20190705151100&vnp_ResponseCode=00&vnp_TmnCode=COCOSIN&vnp_TransactionNo=496558&vnp_TransactionStatus=01&vnp_TxnRef=1562314234&vnp_SecureHash=20fb4aed508f697eb0019b48c7a5e2e80007ad19f9c20fb5bb45717437150d5f26a0f71f966e8ec9e0dfed587e2d9222474ef012181738fd9b84316fa30a77d6 \ No newline at end of file diff --git a/tests/Mock/RefundSuccess.txt b/tests/Mock/RefundSuccess.txt index 704898f..c5c125a 100644 --- a/tests/Mock/RefundSuccess.txt +++ b/tests/Mock/RefundSuccess.txt @@ -4,4 +4,4 @@ Server: Apache Connection: close Content-Type: text/plain; charset=utf-8 -vnp_Amount=1000000&vnp_Message=QueryDR+Success&vnp_OrderInfo=1562314234&vnp_PayDate=20190705151100&vnp_ResponseCode=00&vnp_TmnCode=COCOSIN&vnp_TransactionNo=496558&vnp_TransactionStatus=01&vnp_TxnRef=1562314234&vnp_SecureHash=8c3f728cef087916f1f7f2995106ec27 \ No newline at end of file +vnp_Amount=1000000&vnp_Message=QueryDR+Success&vnp_OrderInfo=1562314234&vnp_PayDate=20190705151100&vnp_ResponseCode=00&vnp_TmnCode=COCOSIN&vnp_TransactionNo=496558&vnp_TransactionStatus=01&vnp_TxnRef=1562314234&vnp_SecureHash=20fb4aed508f697eb0019b48c7a5e2e80007ad19f9c20fb5bb45717437150d5f26a0f71f966e8ec9e0dfed587e2d9222474ef012181738fd9b84316fa30a77d6 \ No newline at end of file diff --git a/tests/Mock/SignatureMock.php b/tests/Mock/SignatureMock.php deleted file mode 100644 index d427962..0000000 --- a/tests/Mock/SignatureMock.php +++ /dev/null @@ -1,18 +0,0 @@ - Date: Wed, 13 Sep 2023 05:24:05 +0700 Subject: [PATCH 23/32] update comment --- src/Concerns/Parameters.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/Parameters.php b/src/Concerns/Parameters.php index 8cee1e5..9ed35d8 100644 --- a/src/Concerns/Parameters.php +++ b/src/Concerns/Parameters.php @@ -25,7 +25,7 @@ public function getVnpVersion(): ?string } /** - * Thiết lập mã Tmn. + * Thiết lập mã Version * * @param null|string $code * @return $this From bea34d59ef963ead640a256f569114c14ce2fc3b Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 05:24:28 +0700 Subject: [PATCH 24/32] wip --- src/Concerns/Parameters.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/Parameters.php b/src/Concerns/Parameters.php index 9ed35d8..1fbb414 100644 --- a/src/Concerns/Parameters.php +++ b/src/Concerns/Parameters.php @@ -15,7 +15,7 @@ trait Parameters { /** - * Trả về mã Tmn do VNPay cấp. + * Trả về mã Vesion * * @return null|string */ From aa4c5084fab220ebb2e71391246ec1f6a5e7617d Mon Sep 17 00:00:00 2001 From: bangnokia Date: Wed, 13 Sep 2023 05:24:47 +0700 Subject: [PATCH 25/32] wip --- src/Concerns/Parameters.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Concerns/Parameters.php b/src/Concerns/Parameters.php index 1fbb414..8c507b5 100644 --- a/src/Concerns/Parameters.php +++ b/src/Concerns/Parameters.php @@ -15,7 +15,7 @@ trait Parameters { /** - * Trả về mã Vesion + * Trả về mã Version * * @return null|string */ From 59178e311ca15284f1c4088dd528b72824fb9ade Mon Sep 17 00:00:00 2001 From: bangnokia Date: Thu, 14 Sep 2023 16:38:53 +0700 Subject: [PATCH 26/32] update to publish to packagist myself --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d0ebca6..359cc74 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "phpviet/omnipay-vnpay", + "name": "bangnokia/omnipay-vnpay", "type": "library", "description": "Thư viện hổ trợ tích hợp cổng thanh toán VNPay.", "keywords": [ @@ -10,7 +10,7 @@ "payment-gateway", "vietnam-payment-gateway" ], - "homepage": "https://github.com/phpviet/omnipay-vnpay", + "homepage": "https://github.com/bangnokia/omnipay-vnpay", "license": "MIT", "authors": [ { From 474889ec120bdc4bf9648bd4f138817be0b05dbc Mon Sep 17 00:00:00 2001 From: bangnokia Date: Thu, 14 Sep 2023 16:41:23 +0700 Subject: [PATCH 27/32] revert --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 359cc74..d0ebca6 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "bangnokia/omnipay-vnpay", + "name": "phpviet/omnipay-vnpay", "type": "library", "description": "Thư viện hổ trợ tích hợp cổng thanh toán VNPay.", "keywords": [ @@ -10,7 +10,7 @@ "payment-gateway", "vietnam-payment-gateway" ], - "homepage": "https://github.com/bangnokia/omnipay-vnpay", + "homepage": "https://github.com/phpviet/omnipay-vnpay", "license": "MIT", "authors": [ { From bd06911e9e33354f9a444e2091a86cdad0475f8e Mon Sep 17 00:00:00 2001 From: bangnokia Date: Mon, 18 Sep 2023 11:45:05 +0700 Subject: [PATCH 28/32] change name to publish on composer --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d0ebca6..348c150 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "phpviet/omnipay-vnpay", + "name": "swebvn/omnipay-vnpay", "type": "library", "description": "Thư viện hổ trợ tích hợp cổng thanh toán VNPay.", "keywords": [ @@ -10,7 +10,7 @@ "payment-gateway", "vietnam-payment-gateway" ], - "homepage": "https://github.com/phpviet/omnipay-vnpay", + "homepage": "https://github.com/swebvn/omnipay-vnpay", "license": "MIT", "authors": [ { From 752c8a5c555834a14eb17d8a1a79c2162c13c3e8 Mon Sep 17 00:00:00 2001 From: bangnokia Date: Mon, 18 Sep 2023 12:07:57 +0700 Subject: [PATCH 29/32] rollback name --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 348c150..d0ebca6 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "swebvn/omnipay-vnpay", + "name": "phpviet/omnipay-vnpay", "type": "library", "description": "Thư viện hổ trợ tích hợp cổng thanh toán VNPay.", "keywords": [ @@ -10,7 +10,7 @@ "payment-gateway", "vietnam-payment-gateway" ], - "homepage": "https://github.com/swebvn/omnipay-vnpay", + "homepage": "https://github.com/phpviet/omnipay-vnpay", "license": "MIT", "authors": [ { From a434655f0235c966cd91f585e855d9d5b55bf00d Mon Sep 17 00:00:00 2001 From: bangnokia Date: Mon, 25 Sep 2023 11:09:04 +0700 Subject: [PATCH 30/32] remove unused parameter --- src/Message/Concerns/RequestSignature.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Message/Concerns/RequestSignature.php b/src/Message/Concerns/RequestSignature.php index 14f8ac8..e3f27a4 100644 --- a/src/Message/Concerns/RequestSignature.php +++ b/src/Message/Concerns/RequestSignature.php @@ -18,10 +18,9 @@ trait RequestSignature /** * Trả về chữ ký điện tử gửi đến VNPay dựa theo [[getSignatureParameters()]]. * - * @param string $hashType * @return string */ - protected function generateSignature(string $hashType = 'sha512'): string + protected function generateSignature(): string { $data = []; From 0be1d86498fd6ff99df0a9505283f950c9acbffb Mon Sep 17 00:00:00 2001 From: bangnokia Date: Mon, 25 Sep 2023 11:12:52 +0700 Subject: [PATCH 31/32] update packages usage in composer.json --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index d0ebca6..3b8b6f0 100644 --- a/composer.json +++ b/composer.json @@ -20,13 +20,13 @@ ], "require": { "php": "^7.4|^8", - "omnipay/common": "^3.0", - "php-http/guzzle7-adapter": "^1.0" + "omnipay/common": "^3.0" }, "require-dev": { "http-interop/http-factory-guzzle": "^1.2", "omnipay/tests": "^4.0", - "scrutinizer/ocular": "^1.5" + "scrutinizer/ocular": "^1.5", + "php-http/guzzle7-adapter": "^1.0" }, "autoload": { "psr-4": { @@ -44,7 +44,7 @@ "config": { "sort-packages": true, "allow-plugins": { - "php-http/discovery": true + "php-http/discovery": false } }, "extra": { From 26dc713febdc62af05d85d6e14920ce2aa6ac2da Mon Sep 17 00:00:00 2001 From: bangnokia Date: Mon, 25 Sep 2023 11:15:43 +0700 Subject: [PATCH 32/32] update composer.json --- composer.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 3b8b6f0..b55e4e4 100644 --- a/composer.json +++ b/composer.json @@ -42,10 +42,7 @@ "test": "\"vendor/bin/phpunit\"" }, "config": { - "sort-packages": true, - "allow-plugins": { - "php-http/discovery": false - } + "sort-packages": true }, "extra": { "branch-alias": {