From 09ef5be5d6f388544d0af4ca03a0b73aa089b18c Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Sun, 6 Mar 2022 10:32:23 +0100 Subject: [PATCH 1/3] issue #50 fix undefined index on fail response --- src/Gateways/GarantiPos.php | 87 +++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/src/Gateways/GarantiPos.php b/src/Gateways/GarantiPos.php index 049206e3..1f9348b6 100644 --- a/src/Gateways/GarantiPos.php +++ b/src/Gateways/GarantiPos.php @@ -622,6 +622,7 @@ protected function getMode() } /** + * todo use tDPayResponseCommon() method to map response * @inheritDoc */ protected function map3DPaymentData($raw3DAuthResponseData, $rawPaymentResponseData) @@ -694,15 +695,46 @@ protected function map3DPaymentData($raw3DAuthResponseData, $rawPaymentResponseD */ protected function map3DPayResponseData($raw3DAuthResponseData) { + $commonResult = $this->tDPayResponseCommon($raw3DAuthResponseData); + + if ('approved' === $commonResult['status']) { + //these data only available on success + $commonResult['id'] = $raw3DAuthResponseData['authcode']; + $commonResult['auth_code'] = $raw3DAuthResponseData['authcode']; + $commonResult['trans_id'] = $raw3DAuthResponseData['transid']; + $commonResult['host_ref_num'] = $raw3DAuthResponseData['hostrefnum']; + $commonResult['rand'] = $raw3DAuthResponseData['rnd']; + $commonResult['hash_params'] = $raw3DAuthResponseData['hashparams']; + $commonResult['hash_params_val'] = $raw3DAuthResponseData['hashparamsval']; + $commonResult['masked_number'] = $raw3DAuthResponseData['MaskedPan']; + $commonResult['tx_status'] = $raw3DAuthResponseData['txnstatus']; + $commonResult['eci'] = $raw3DAuthResponseData['eci']; + $commonResult['cavv'] = $raw3DAuthResponseData['cavv']; + $commonResult['xid'] = $raw3DAuthResponseData['xid']; + } + + return (object) $commonResult; + } + + /** + * @param array $raw3DAuthResponseData + * + * @return array + */ + protected function tDPayResponseCommon(array $raw3DAuthResponseData): array + { + $procReturnCode = $raw3DAuthResponseData['procreturncode']; + $mdStatus = $raw3DAuthResponseData['mdstatus']; + $status = 'declined'; $response = 'Declined'; - $procReturnCode = $raw3DAuthResponseData['procreturncode']; $transactionSecurity = 'MPI fallback'; - if (in_array($raw3DAuthResponseData['mdstatus'], [1, 2, 3, 4]) && $raw3DAuthResponseData['response'] !== $response) { - if ($raw3DAuthResponseData['mdstatus'] == '1') { + if (in_array($mdStatus, ['1', '2', '3', '4']) && 'Error' !== $raw3DAuthResponseData['response']) { + if ('1' === $mdStatus) { $transactionSecurity = 'Full 3D Secure'; - } elseif (in_array($raw3DAuthResponseData['mdstatus'], [2, 3, 4])) { + } else { + //['2', '3', '4'] $transactionSecurity = 'Half 3D Secure'; } @@ -710,12 +742,12 @@ protected function map3DPayResponseData($raw3DAuthResponseData) $response = 'Approved'; } - return (object) [ - 'id' => (string) $raw3DAuthResponseData['authcode'], - 'order_id' => (string) $raw3DAuthResponseData['oid'], - 'trans_id' => (string) $raw3DAuthResponseData['transid'], - 'auth_code' => (string) $raw3DAuthResponseData['authcode'], - 'host_ref_num' => (string) $raw3DAuthResponseData['hostrefnum'], + return [ + 'id' => null, + 'order_id' => $raw3DAuthResponseData['oid'], + 'trans_id' => null, + 'auth_code' => null, + 'host_ref_num' => null, 'response' => $response, 'transaction_type' => $this->type, 'transaction' => $this->type, @@ -724,25 +756,24 @@ protected function map3DPayResponseData($raw3DAuthResponseData) 'code' => $procReturnCode, 'md_status' => $raw3DAuthResponseData['mdstatus'], 'status' => $status, - 'status_detail' => isset($this->codes[$raw3DAuthResponseData['procreturncode']]) ? (string) $raw3DAuthResponseData['procreturncode'] : null, - 'hash' => (string) $raw3DAuthResponseData['secure3dhash'], - 'rand' => (string) $raw3DAuthResponseData['rnd'], - 'hash_params' => (string) $raw3DAuthResponseData['hashparams'], - 'hash_params_val' => (string) $raw3DAuthResponseData['hashparamsval'], - 'masked_number' => (string) $raw3DAuthResponseData['MaskedPan'], - 'amount' => (string) $raw3DAuthResponseData['txnamount'], - 'currency' => (string) $raw3DAuthResponseData['txncurrencycode'], - 'tx_status' => (string) $raw3DAuthResponseData['txnstatus'], - 'eci' => (string) $raw3DAuthResponseData['eci'], - 'cavv' => (string) $raw3DAuthResponseData['cavv'], - 'xid' => (string) $raw3DAuthResponseData['xid'], - 'error_code' => (string) isset($raw3DAuthResponseData['errcode'])?$raw3DAuthResponseData['errcode']:null, - 'error_message' => (string) $raw3DAuthResponseData['errmsg'], - 'md_error_message' => (string) $raw3DAuthResponseData['mderrormessage'], + 'status_detail' => isset($this->codes[$procReturnCode]) ? $procReturnCode : null, + 'hash' => $raw3DAuthResponseData['secure3dhash'], + 'rand' => null, + 'hash_params' => null, + 'hash_params_val' => null, + 'masked_number' => null, + 'amount' => $raw3DAuthResponseData['txnamount'], + 'currency' => $raw3DAuthResponseData['txncurrencycode'], + 'tx_status' => null, + 'eci' => null, + 'cavv' => null, + 'xid' => null, + 'error_code' => 'Error' === $raw3DAuthResponseData['response'] ? $procReturnCode: null, + 'error_message' => $raw3DAuthResponseData['errmsg'], + 'md_error_message' => $raw3DAuthResponseData['mderrormessage'], 'campaign_url' => null, - //'name' => (string) $raw3DAuthResponseData['firmaadi'], - 'email' => (string) $raw3DAuthResponseData['customeremailaddress'], - 'extra' => $raw3DAuthResponseData['Extra'] ?? null, + 'email' => $raw3DAuthResponseData['customeremailaddress'], + 'extra' => null, 'all' => $raw3DAuthResponseData, ]; } From 0b113900ed1b6286040e2bc8e982ad2a9a93b4cb Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Sun, 6 Mar 2022 10:34:09 +0100 Subject: [PATCH 2/3] added more unit tests for GarantiPos::map3DPayResponseData() --- tests/Gateways/GarantiPosTest.php | 113 ++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/tests/Gateways/GarantiPosTest.php b/tests/Gateways/GarantiPosTest.php index 7d61c619..f1f40d62 100644 --- a/tests/Gateways/GarantiPosTest.php +++ b/tests/Gateways/GarantiPosTest.php @@ -9,6 +9,8 @@ use Mews\Pos\Gateways\AbstractGateway; use Mews\Pos\Gateways\GarantiPos; use PHPUnit\Framework\TestCase; +use ReflectionClass; +use ReflectionMethod; use Symfony\Component\Serializer\Encoder\XmlEncoder; class GarantiPosTest extends TestCase @@ -319,6 +321,108 @@ public function testCreateRefundXML() //$this->assertEquals([], $actualData['Transaction']); } + /** + * @uses \Mews\Pos\Gateways\GarantiPos::map3DPayResponseData() + * + * @return void + */ + public function testMap3DPayResponseDataSuccess() + { + $gatewayResponse = [ + "xid" => "bVi+A/h6SjXabcde=", + "mdstatus" => "1", + "mderrormessage" => "TROY Gateway Result: [Code: '000', Message: 'Success', Description: 'Successful']", + "txnstatus" => "", + "eci" => "", + "cavv" => "ABIBBDYABBBBBAAABAAAAAAAAAAA=", + "paressyntaxok" => "", + "paresverified" => "", + "version" => "", + "ireqcode" => "", + "ireqdetail" => "", + "vendorcode" => "", + "cavvalgorithm" => "", + "md" => "longstring", + "terminalid" => "10012345", + "oid" => "1221513409", + "authcode" => "", + "response" => "", + "errmsg" => "", + "hostmsg" => "", + "procreturncode" => "", + "transid" => "1001513409", + "hostrefnum" => "", + "rnd" => "vNOc4abcde2aCL/HBzs", + "hash" => "1I9zDunx0hashTRI816trOG0Ao0=", + "hashparams" => "clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:", + "hashparamsval" => "longstring", + "clientid" => "10012345", + "MaskedPan" => "454311***7965", + "customeripaddress" => "134.170.165.149", + "orderid" => "1221513409", + "txntype" => "sales", + "terminalprovuserid" => "PROVAUT", + "secure3dhash" => "BE3C507794AhashE021E8EA239415D774EEF2", + "mode" => "PROD", + "txncurrencycode" => "949", + "customeremailaddress" => "admin@admin.com", + "terminaluserid" => "PROVAUT", + "terminalmerchantid" => "1234567", + "secure3dsecuritylevel" => "3D", + "user_id" => "1", + "errorurl" => "https://example.com/odeme_basarisiz", + "apiversion" => "v0.01", + "txnamount" => "100", + "txninstallmentcount" => "", + "successurl" => "https://example.com/odeme_basarili", + ]; + $expected = '{"id":"","order_id":"1221513409","trans_id":"1001513409","auth_code":"","host_ref_num":"","response":"Approved","transaction_type":null,"transaction":null,"transaction_security":"Full 3D Secure","proc_return_code":"","code":"","md_status":"1","status":"approved","status_detail":null,"hash":"BE3C507794AhashE021E8EA239415D774EEF2","rand":"vNOc4abcde2aCL\/HBzs","hash_params":"clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:","hash_params_val":"longstring","masked_number":"454311***7965","amount":"100","currency":"949","tx_status":"","eci":"","cavv":"ABIBBDYABBBBBAAABAAAAAAAAAAA=","xid":"bVi+A\/h6SjXabcde=","error_code":null,"error_message":"","md_error_message":"TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']","campaign_url":null,"email":"admin@admin.com","extra":null,"all":{"xid":"bVi+A\/h6SjXabcde=","mdstatus":"1","mderrormessage":"TROY Gateway Result: [Code: \'000\', Message: \'Success\', Description: \'Successful\']","txnstatus":"","eci":"","cavv":"ABIBBDYABBBBBAAABAAAAAAAAAAA=","paressyntaxok":"","paresverified":"","version":"","ireqcode":"","ireqdetail":"","vendorcode":"","cavvalgorithm":"","md":"longstring","terminalid":"10012345","oid":"1221513409","authcode":"","response":"","errmsg":"","hostmsg":"","procreturncode":"","transid":"1001513409","hostrefnum":"","rnd":"vNOc4abcde2aCL\/HBzs","hash":"1I9zDunx0hashTRI816trOG0Ao0=","hashparams":"clientid:oid:authcode:procreturncode:response:mdstatus:cavv:eci:md:rnd:","hashparamsval":"longstring","clientid":"10012345","MaskedPan":"454311***7965","customeripaddress":"134.170.165.149","orderid":"1221513409","txntype":"sales","terminalprovuserid":"PROVAUT","secure3dhash":"BE3C507794AhashE021E8EA239415D774EEF2","mode":"PROD","txncurrencycode":"949","customeremailaddress":"admin@admin.com","terminaluserid":"PROVAUT","terminalmerchantid":"1234567","secure3dsecuritylevel":"3D","user_id":"1","errorurl":"https:\/\/example.com\/odeme_basarisiz","apiversion":"v0.01","txnamount":"100","txninstallmentcount":"","successurl":"https:\/\/example.com\/odeme_basarili"}}'; + $method = $this->getMethod('map3DPayResponseData'); + $result1 = $method->invoke($this->pos, $gatewayResponse); + + $this->assertSame($expected, json_encode($result1)); + } + + /** + * @uses \Mews\Pos\Gateways\GarantiPos::map3DPayResponseData() + * + * @return void + */ + public function testMap3DPayResponseDataFail() + { + $failResponse = [ + "mdstatus" => "0", + "mderrormessage" => "User Gave Up", + "errmsg" => "User Gave Up", + "clientid" => "10012345", + "oid" => "1221166825", + "response" => "Error", + "procreturncode" => "99", + "customeripaddress" => "111.222.333.444", + "orderid" => "1221166825", + "txntype" => "sales", + "terminalprovuserid" => "PROVAUT", + "secure3dhash" => "hashhash", + "mode" => "PROD", + "terminalid" => "10012345", + "txncurrencycode" => "949", + "customeremailaddress" => "admin@admin.com", + "terminaluserid" => "PROVAUT", + "terminalmerchantid" => "5220607", + "secure3dsecuritylevel" => "3D", + "user_id" => "1", + "errorurl" => "https://example.com/odeme_basarisiz", + "apiversion" => "v0.01", + "txnamount" => "9000", + "txninstallmentcount" => "", + "successurl" => "https://example.com/odeme_basarili", + ]; + $expected = '{"id":null,"order_id":"1221166825","trans_id":null,"auth_code":null,"host_ref_num":null,"response":"Declined","transaction_type":null,"transaction":null,"transaction_security":"MPI fallback","proc_return_code":"99","code":"99","md_status":"0","status":"declined","status_detail":"99","hash":"hashhash","rand":null,"hash_params":null,"hash_params_val":null,"masked_number":null,"amount":"9000","currency":"949","tx_status":null,"eci":null,"cavv":null,"xid":null,"error_code":"99","error_message":"User Gave Up","md_error_message":"User Gave Up","campaign_url":null,"email":"admin@admin.com","extra":null,"all":{"mdstatus":"0","mderrormessage":"User Gave Up","errmsg":"User Gave Up","clientid":"10012345","oid":"1221166825","response":"Error","procreturncode":"99","customeripaddress":"111.222.333.444","orderid":"1221166825","txntype":"sales","terminalprovuserid":"PROVAUT","secure3dhash":"hashhash","mode":"PROD","terminalid":"10012345","txncurrencycode":"949","customeremailaddress":"admin@admin.com","terminaluserid":"PROVAUT","terminalmerchantid":"5220607","secure3dsecuritylevel":"3D","user_id":"1","errorurl":"https:\/\/example.com\/odeme_basarisiz","apiversion":"v0.01","txnamount":"9000","txninstallmentcount":"","successurl":"https:\/\/example.com\/odeme_basarili"}}'; + $method = $this->getMethod('map3DPayResponseData'); + $result1 = $method->invoke($this->pos, $failResponse); + $this->assertSame($expected, json_encode($result1)); + } + /** * @param $order * @param CreditCardGarantiPos $card @@ -597,4 +701,13 @@ private function getSampleRefundXMLData($order, $account) ], ]; } + + private static function getMethod(string $name): ReflectionMethod + { + $class = new ReflectionClass(GarantiPos::class); + $method = $class->getMethod($name); + $method->setAccessible(true); + + return $method; + } } From dbd1e8312a0639ac592d02cb43d061b232688a50 Mon Sep 17 00:00:00 2001 From: Nuryagdy Mustapayev Date: Sun, 6 Mar 2022 10:38:52 +0100 Subject: [PATCH 3/3] added more unit tests for GarantiPos::map3DPayResponseData() --- tests/Gateways/GarantiPosTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Gateways/GarantiPosTest.php b/tests/Gateways/GarantiPosTest.php index f1f40d62..1717fddf 100644 --- a/tests/Gateways/GarantiPosTest.php +++ b/tests/Gateways/GarantiPosTest.php @@ -380,6 +380,7 @@ public function testMap3DPayResponseDataSuccess() $method = $this->getMethod('map3DPayResponseData'); $result1 = $method->invoke($this->pos, $gatewayResponse); + $this->assertIsObject($result1); $this->assertSame($expected, json_encode($result1)); }