diff --git a/README.md b/README.md index 0563885..3f62cf9 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,13 @@ openssl req -new -key development.key -out VNNNNNNN_YYYYMMDD_D.csr ## Usage +**IMPORTANT**: Switch signing schema MAC_EXTENDED / MAC_ADVANCED with methods: +````php +$saleRequest->setSigningSchemaMacExtended(); // use MAC_EXTENDED +$saleRequest->setSigningSchemaMacAdvanced(); // use MAC_ADVANCED +```` +Default signing schema is **MAC_ADVANCED**! + ### Sale request ````php @@ -61,6 +68,8 @@ $saleRequest = (new SaleRequest()) ->setTerminalID('') ->setMerchantId('') ->setPrivateKey('\', '') + //->setSigningSchemaMacExtended(); // use MAC_EXTENDED + //->setSigningSchemaMacAdvanced(); // use MAC_ADVANCED ->setPrivateKeyPassword('test'); $formHtml = $saleRequest->generateForm(); // only generate hidden html form with filled inputs diff --git a/src/Base.php b/src/Base.php index 0117998..1306e63 100644 --- a/src/Base.php +++ b/src/Base.php @@ -14,11 +14,26 @@ abstract class Base { + const SIGNING_SCHEMA_MAC_ADVANCED = 'MAC_ADVANCED'; + const SIGNING_SCHEMA_MAC_EXTENDED = 'MAC_EXTENDED'; + + /** + * Default signing schema + * + * @var string + */ + protected $signingSchema = self::SIGNING_SCHEMA_MAC_ADVANCED; + /** * @var string */ protected $merchantId; + /** + * @var string + */ + protected $publicKey; + /** * @var string */ @@ -44,15 +59,11 @@ abstract class Base /** * In develop mode of application + * * @var string */ private $environment = 'production'; - /** - * @var string - */ - protected $publicKey; - /** * @return boolean */ @@ -82,6 +93,7 @@ public function getEnvironmentUrl() /** * Switch environment to development/production + * * @param boolean $production True - production / false - development. * * @return Base @@ -98,6 +110,7 @@ public function setEnvironment($production = true) /** * Switch to production mode + * * @return Base */ public function inProduction() @@ -108,6 +121,7 @@ public function inProduction() /** * Switch to development mode + * * @return Base */ public function inDevelopment() @@ -118,6 +132,7 @@ public function inDevelopment() /** * Get terminal ID + * * @return mixed */ public function getTerminalID() @@ -127,7 +142,9 @@ public function getTerminalID() /** * Set terminal ID + * * @param string $terminalID Terminal ID. + * * @return Base * @throws ParameterValidationException */ @@ -167,9 +184,71 @@ public function setMerchantId($merchantId) return $this; } + /** + * Switch signing schema to MAC_ADVANCED + * + * @return Base + */ + public function setSigningSchemaMacAdvanced() + { + $this->signingSchema = self::SIGNING_SCHEMA_MAC_ADVANCED; + return $this; + } + + /** + * Switch signing schema to MAC_EXTENDED + * + * @return Base + */ + public function setSigningSchemaMacExtended() + { + $this->signingSchema = self::SIGNING_SCHEMA_MAC_EXTENDED; + return $this; + } + + /** + * Get public key + * + * @return string + * @throws ParameterValidationException + */ + public function getPublicKey() + { + if (empty($this->publicKey)) { + throw new ParameterValidationException('Please set public key first!'); + } + + return $this->publicKey; + } + + /** + * Set public key + * + * @param string $publicKey Public key path. + * + * @return Base + */ + public function setPublicKey($publicKey) + { + $this->publicKey = $publicKey; + return $this; + } + + /** + * Is MAC_ADVANCE signing schema? + * + * @return boolean + */ + protected function isSigningSchemaMacAdvanced() + { + return $this->signingSchema == self::SIGNING_SCHEMA_MAC_ADVANCED; + } + /** * Generate signature of data with private key + * * @param array $data Данни върху които да генерира подписа. + * * @return string * @throws SignatureException */ @@ -193,10 +272,10 @@ protected function getPrivateSignature(array $data) if (PHP_MAJOR_VERSION < 8) { /** * @deprecated in PHP 8.0 - * @note The openssl_pkey_free() function is deprecated and no longer has an effect, + * @note The openssl_pkey_free() function is deprecated and no longer has an effect, * instead the OpenSSLAsymmetricKey instance is automatically destroyed if it is no * longer referenced. - * @see https://github.com/php/php-src/blob/master/UPGRADING#L397 + * @see https://github.com/php/php-src/blob/master/UPGRADING#L397 */ openssl_pkey_free($privateKey); } @@ -206,8 +285,10 @@ protected function getPrivateSignature(array $data) /** * Generate signature source + * * @param array $data Data of signature. * @param boolean $isResponse Generate signature from response. + * * @return string */ protected function getSignatureSource(array $data, $isResponse = false) @@ -225,6 +306,7 @@ protected function getSignatureSource(array $data, $isResponse = false) /** * Get private key + * * @return string */ public function getPrivateKey() @@ -234,8 +316,10 @@ public function getPrivateKey() /** * Set private key + * * @param string $privateKeyPath Път до файла на частният ключ. * @param string|null $password Парола на частният ключ. + * * @return Base */ public function setPrivateKey($privateKeyPath, $password = null) @@ -251,6 +335,7 @@ public function setPrivateKey($privateKeyPath, $password = null) /** * Get private key password + * * @return string|null */ public function getPrivateKeyPassword() @@ -260,7 +345,9 @@ public function getPrivateKeyPassword() /** * Set private key password + * * @param string|null $privateKeyPassword Парола на частният ключ. + * * @return Base */ public function setPrivateKeyPassword($privateKeyPassword) @@ -268,32 +355,4 @@ public function setPrivateKeyPassword($privateKeyPassword) $this->privateKeyPassword = $privateKeyPassword; return $this; } - - /** - * Get public key - * - * @return string - * @throws ParameterValidationException - */ - public function getPublicKey() - { - if (empty($this->publicKey)) { - throw new ParameterValidationException('Please set public key first!'); - } - - return $this->publicKey; - } - - /** - * Set public key - * - * @param string $publicKey Public key path. - * - * @return Base - */ - public function setPublicKey($publicKey) - { - $this->publicKey = $publicKey; - return $this; - } } diff --git a/src/Response.php b/src/Response.php index b06c70e..4580749 100644 --- a/src/Response.php +++ b/src/Response.php @@ -55,22 +55,7 @@ protected function verifyData() return; } - $verifyingFields = [ - 'ACTION', - 'RC', - 'APPROVAL', - 'TERMINAL', - 'TRTYPE', - 'AMOUNT', - 'CURRENCY', - 'ORDER', - 'RRN', - 'INT_REF', - 'PARES_STATUS', - 'ECI', - 'TIMESTAMP', - 'NONCE', - ]; + $verifyingFields = $this->getVerifyingFields(); $dataToVerify = []; @@ -90,7 +75,8 @@ protected function verifyData() /** * това нямам идея защо така са го направили... но да :/ - * @see 5.2 от документацията + * + * @see 5.2 от документацията * @note прави се само за TRTYPE = 90! */ if ($key == 'CURRENCY' && empty($responseFromBorica[$key]) && $responseFromBorica['TRTYPE'] == 90) { @@ -106,6 +92,67 @@ protected function verifyData() $this->dataIsVerified = true; } + /** + * @return string[] + */ + protected function getVerifyingFields() + { + return [ + 'ACTION', + 'RC', + 'APPROVAL', + 'TERMINAL', + 'TRTYPE', + 'AMOUNT', + 'CURRENCY', + 'ORDER', + 'RRN', + 'INT_REF', + 'PARES_STATUS', + 'ECI', + 'TIMESTAMP', + 'NONCE', + ]; + } + + /** + * Get response data + * + * @note If response data is not set - set data to $_POST + * + * @param boolean $verify Verify data before return. + * + * @return array + * @throws ParameterValidationException + * @throws SignatureException + */ + public function getResponseData($verify = true) + { + if (empty($this->responseData)) { + $this->setResponseData($_POST); + } + + if ($verify) { + $this->verifyData(); + } + + return $this->responseData; + } + + /** + * Set response data + * + * @param array $responseData Response data from borica. + * + * @return Response + */ + public function setResponseData(array $responseData) + { + $this->dataIsVerified = false; + $this->responseData = $responseData; + return $this; + } + /** * Verify data with public certificate * @@ -156,42 +203,4 @@ protected function verifyPublicSignature(array $data, $publicSignature) openssl_pkey_free($publicKey); } } - - /** - * Get response data - * - * @note If response data is not set - set data to $_POST - * - * @param boolean $verify Verify data before return. - * - * @return array - * @throws ParameterValidationException - * @throws SignatureException - */ - public function getResponseData($verify = true) - { - if (empty($this->responseData)) { - $this->setResponseData($_POST); - } - - if ($verify) { - $this->verifyData(); - } - - return $this->responseData; - } - - /** - * Set response data - * - * @param array $responseData Response data from borica. - * - * @return Response - */ - public function setResponseData(array $responseData) - { - $this->dataIsVerified = false; - $this->responseData = $responseData; - return $this; - } } diff --git a/src/SaleRequest.php b/src/SaleRequest.php index 13d9f06..16f1c91 100644 --- a/src/SaleRequest.php +++ b/src/SaleRequest.php @@ -164,6 +164,20 @@ public function getData() public function generateSignature() { $this->validateRequiredParameters(); + + if ($this->isSigningSchemaMacAdvanced()) { + return $this->getPrivateSignature([ + $this->getTerminalID(), + $this->getTransactionType()->getValue(), + $this->getAmount(), + $this->getCurrency(), + $this->getOrder(), + $this->getSignatureTimestamp(), + $this->getNonce() + ]); + } + + // MAC_EXTENDED return $this->getPrivateSignature([ $this->getTerminalID(), $this->getTransactionType()->getValue(), diff --git a/tests/SaleRequestTest.php b/tests/SaleRequestTest.php index 846159a..8a32c69 100644 --- a/tests/SaleRequestTest.php +++ b/tests/SaleRequestTest.php @@ -30,7 +30,8 @@ public function testSignature() ->setPrivateKey(__DIR__ . '/certificates/test.key') ->setPrivateKeyPassword('test') ->setSignatureTimestamp('20201013115715') - ->setNonce('FC8AC36A9FDADCB6127D273CD15DAEC3'); + ->setNonce('FC8AC36A9FDADCB6127D273CD15DAEC3') + ->setSigningSchemaMacExtended(); $this->assertEquals( '8125E0E604B8BC6430B03B1365B63D91ACB7210F2777776D7587A633D222368CB36936855090C81020318503998499503595EBB32092014A2843C7E6DB75C1AD7FCB018BB4CDA98B379B411E74C62881529A7787B73D8D0E00D1406E1D2A64ADD1A298CCDF3B5A13C14825990010541444122F4A8FBB23BB3747B962BEFB5C57C5737FCF8DC9E61F377777B661B04FFE604EE5E49EB87CA49737FD39AA27639DE0CEF11B527B630070BE97ECC81F0D14D355F37C5C684A040C615563C962CE137A0B7C7F0B3567DEB0A05C4D79F373D7938D4CBFCE86CA6AA5DBAC99081F3AB4C52E0A3B35748A7600ECE4278060B14F5D3ACE5D964A73F49CF8844B6C86E10E', @@ -57,6 +58,7 @@ public function testData() ->setPrivateKeyPassword('test') ->setSignatureTimestamp('20201013115715') ->setNonce('FC8AC36A9FDADCB6127D273CD15DAEC3') + ->setSigningSchemaMacExtended() ->getData(); $this->assertEquals([