diff --git a/src/Gateway.php b/src/Gateway.php index f446727..103cf9d 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -3,6 +3,8 @@ namespace Omnipay\Gomypay; use Omnipay\Common\AbstractGateway; +use Omnipay\Gomypay\Message\AcceptNotificationRequest; +use Omnipay\Gomypay\Message\CompletePurchaseRequest; use Omnipay\Gomypay\Message\PurchaseRequest; use Omnipay\Gomypay\Traits\HasGomypay; @@ -32,6 +34,16 @@ public function purchase(array $options = []) return $this->createRequest(PurchaseRequest::class, $options); } + public function completePurchase(array $options = []) + { + return $this->createRequest(CompletePurchaseRequest::class, $options); + } + + public function acceptNotification(array $options = []) + { + return $this->createRequest(AcceptNotificationRequest::class, $options); + } + public function getPaymentInfo(array $options = []) { return $this->createRequest(GetPaymentInfoRequest::class, $options); diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index 9b0c867..43b6aed 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -4,9 +4,6 @@ use Omnipay\Common\Message\AbstractRequest as BaseAbstractRequest; -/** - * Abstract Request - */ abstract class AbstractRequest extends BaseAbstractRequest { protected $liveEndpoint = 'https://n.gomypay.asia/ShuntClass.aspx'; diff --git a/src/Message/AcceptNotificationRequest.php b/src/Message/AcceptNotificationRequest.php new file mode 100644 index 0000000..3866d4e --- /dev/null +++ b/src/Message/AcceptNotificationRequest.php @@ -0,0 +1,58 @@ +httpRequest->request->all(); + } + + /** + * @throws InvalidRequestException + * @throws InvalidResponseException + */ + public function sendData($data) + { + $data = array_merge($data, ['Amount' => (int) $this->getAmount()]); + + if (! hash_equals($this->makeHash($data), $data['str_check'])) { + throw new InvalidResponseException('Invalid hash'); + } + + return $this->response = new AcceptNotificationResponse($this, $data); + } + + public function getTransactionId() + { + return $this->getNotificationResponse()->getTransactionId(); + } + + public function getTransactionReference() + { + return $this->getNotificationResponse()->getTransactionReference(); + } + + public function getTransactionStatus() + { + return $this->getNotificationResponse()->getTransactionStatus(); + } + + public function getMessage() + { + return $this->getNotificationResponse()->getMessage(); + } + + private function getNotificationResponse() + { + return ! $this->response ? $this->send() : $this->response; + } +} diff --git a/src/Message/AcceptNotificationResponse.php b/src/Message/AcceptNotificationResponse.php new file mode 100644 index 0000000..355517b --- /dev/null +++ b/src/Message/AcceptNotificationResponse.php @@ -0,0 +1,13 @@ +isSuccessful() ? self::STATUS_COMPLETED : self::STATUS_FAILED; + } +} diff --git a/src/Message/CompletePurchaseRequest.php b/src/Message/CompletePurchaseRequest.php new file mode 100644 index 0000000..0437e5b --- /dev/null +++ b/src/Message/CompletePurchaseRequest.php @@ -0,0 +1,32 @@ +httpRequest->query->all(); + } + + /** + * @throws InvalidRequestException + * @throws InvalidResponseException + */ + public function sendData($data) + { + $data = array_merge($data, ['Amount' => (int) $this->getAmount()]); + + if (! hash_equals($this->makeHash($data), $data['str_check'])) { + throw new InvalidResponseException('Invalid hash'); + } + + return $this->response = new CompletePurchaseResponse($this, $data); + } +} diff --git a/src/Message/CompletePurchaseResponse.php b/src/Message/CompletePurchaseResponse.php new file mode 100644 index 0000000..bced0b1 --- /dev/null +++ b/src/Message/CompletePurchaseResponse.php @@ -0,0 +1,31 @@ +getCode() === 1; + } + + public function getCode() + { + return $this->data['result']; + } + + public function getMessage() + { + return $this->data['ret_msg']; + } + + public function getTransactionId() + { + return $this->data['e_orderno']; + } + + public function getTransactionReference() + { + return $this->data['OrderID']; + } +} diff --git a/src/Message/GetPaymentInfoRequest.php b/src/Message/GetPaymentInfoRequest.php index 3968c8e..3ecb084 100644 --- a/src/Message/GetPaymentInfoRequest.php +++ b/src/Message/GetPaymentInfoRequest.php @@ -21,19 +21,9 @@ public function getData() */ public function sendData($data) { - $data = array_merge($data, [ - 'CustomerId' => $this->getCustomerId(), - 'Amount' => (int) $this->getAmount(), - 'Str_Check' => $this->getStrCheck(), - ]); + $data = array_merge($data, ['Amount' => (int) $this->getAmount()]); - $keys = ['result', 'e_orderno', 'CustomerId', 'Amount', 'OrderID', 'Str_Check']; - $plainText = ''; - foreach ($keys as $key) { - $plainText .= $data[$key]; - } - $hash = md5($plainText); - if (! hash_equals($hash, $data['str_check'])) { + if (! hash_equals($this->makeHash($data), $data['str_check'])) { throw new InvalidResponseException('Invalid check'); } diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php index b7093b9..8bef897 100644 --- a/src/Message/PurchaseRequest.php +++ b/src/Message/PurchaseRequest.php @@ -6,11 +6,6 @@ use Omnipay\Gomypay\PaymentMethod; use Omnipay\Gomypay\Traits\HasGomypay; -/** - * Authorize Request - * - * @method PurchaseResponse send() - */ class PurchaseRequest extends AbstractRequest { use HasGomypay; diff --git a/src/Message/PurchaseResponse.php b/src/Message/PurchaseResponse.php index 458b3f7..8c90c8a 100644 --- a/src/Message/PurchaseResponse.php +++ b/src/Message/PurchaseResponse.php @@ -18,7 +18,9 @@ public function isRedirect() public function getRedirectUrl() { - return $this->request->getEndpoint(); + return $this->request->getTestMode() + ? 'https://n.gomypay.asia/TestShuntClass.aspx' + : 'https://n.gomypay.asia/ShuntClass.aspx'; } public function getRedirectMethod() diff --git a/src/Traits/HasGomypay.php b/src/Traits/HasGomypay.php index 3b8acb6..f9e0798 100644 --- a/src/Traits/HasGomypay.php +++ b/src/Traits/HasGomypay.php @@ -44,4 +44,25 @@ public function setStr_Check($value) { return $this->setStrCheck($value); } + + public function makeHash(array $data) + { + $amount = 0; + if (array_key_exists('PayAmount', $data)) { + $amount = $data['PayAmount']; + } elseif (array_key_exists('e_money', $data)) { + $amount = $data['e_money']; + } elseif (array_key_exists('Amount', $data)) { + $amount = $data['Amount']; + } + + return md5(implode('', [ + $data['result'], + $data['e_orderno'], + $this->getCustomerId(), + $amount, + $data['OrderID'], + $this->getStrCheck(), + ])); + } } diff --git a/tests/Message/AcceptNotificationRequestTest.php b/tests/Message/AcceptNotificationRequestTest.php new file mode 100644 index 0000000..a919e83 --- /dev/null +++ b/tests/Message/AcceptNotificationRequestTest.php @@ -0,0 +1,169 @@ +request = new AcceptNotificationRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize([ + 'CustomerId' => '80013554', + 'Str_Check' => '2b1bef9d8ab6a81e9a2739c6ecc64ef8', + ]); + } + + public function testGetCreditCardData() + { + $this->getHttpRequest()->request->replace([ + 'Send_Type' => '0', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_Cur' => 'NT', + 'e_money' => '50', + 'e_date' => '20200507', + 'e_time' => '12:30:59', + 'e_orderno' => '2020050701', + 'e_no' => '80013554', + 'e_outlay' => '2', + 'avcode' => '012345', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + 'Invoice_No' => '12345', + 'CardLastNum' => '2222', + ]); + + $this->assertEquals(NotificationInterface::STATUS_COMPLETED, $this->request->getTransactionStatus()); + $this->assertEquals('授權成功', $this->request->getMessage()); + $this->assertEquals('2020050701', $this->request->getTransactionId()); + $this->assertEquals('2020050700000000001', $this->request->getTransactionReference()); + } + + public function testGetUnionPayData() + { + $this->getHttpRequest()->request->replace([ + 'Send_Type' => '1', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_Cur' => 'NT', + 'e_money' => '50', + 'e_date' => '20200507', + 'e_time' => '12:30:59', + 'e_orderno' => '2020050701', + 'e_no' => '80013554', + 'e_outlay' => '2', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + ]); + + $this->assertEquals(NotificationInterface::STATUS_COMPLETED, $this->request->getTransactionStatus()); + $this->assertEquals('授權成功', $this->request->getMessage()); + $this->assertEquals('2020050701', $this->request->getTransactionId()); + $this->assertEquals('2020050700000000001', $this->request->getTransactionReference()); + } + + public function testGetBarcodeData() + { + $this->getHttpRequest()->request->replace([ + 'Send_Type' => '2', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_money' => '100', + 'PayAmount' => '50', + 'e_date' => '20200507', + 'e_time' => '12:30:59', + 'e_orderno' => '2020050701', + 'e_payaccount' => '0055600701508856', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + ]); + + $this->assertEquals(NotificationInterface::STATUS_COMPLETED, $this->request->getTransactionStatus()); + $this->assertEquals('授權成功', $this->request->getMessage()); + $this->assertEquals('2020050701', $this->request->getTransactionId()); + $this->assertEquals('2020050700000000001', $this->request->getTransactionReference()); + } + + public function testGetVirtualAccountData() + { + $this->getHttpRequest()->request->replace([ + 'Send_Type' => '4', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_money' => '100', + 'PayAmount' => '50', + 'e_date' => '20200507', + 'e_time' => '12:30:59', + 'e_orderno' => '2020050701', + 'e_payaccount' => '0055600701508856', + 'e_PayInfo' => '013,08856', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + ]); + + $this->assertEquals(NotificationInterface::STATUS_COMPLETED, $this->request->getTransactionStatus()); + $this->assertEquals('授權成功', $this->request->getMessage()); + $this->assertEquals('2020050701', $this->request->getTransactionId()); + $this->assertEquals('2020050700000000001', $this->request->getTransactionReference()); + } + + public function testGetWebAtmData() + { + $this->getHttpRequest()->request->replace([ + 'Send_Type' => '3', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_money' => '100', + 'PayAmount' => '50', + 'e_date' => '20200507', + 'e_time' => '12:30:59', + 'e_orderno' => '2020050701', + 'e_payaccount' => '0055600701508856', + 'e_PayInfo' => '013,08856', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + ]); + + $this->assertEquals(NotificationInterface::STATUS_COMPLETED, $this->request->getTransactionStatus()); + $this->assertEquals('授權成功', $this->request->getMessage()); + $this->assertEquals('2020050701', $this->request->getTransactionId()); + $this->assertEquals('2020050700000000001', $this->request->getTransactionReference()); + } + + public function testGetCvsData() + { + $this->getHttpRequest()->request->replace([ + 'Send_Type' => '6', + 'StoreType' => '3', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_money' => '100', + 'PayAmount' => '50', + 'e_date' => '20200507', + 'e_time' => '12:30:59', + 'e_orderno' => '2020050701', + 'PinCode' => 'GMPA2018383076', + 'Barcode2' => '123456', + 'Market_ID' => 'SE', + 'Shop_Store_Name' => '7-11(地址)', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + ]); + + $this->assertEquals(NotificationInterface::STATUS_COMPLETED, $this->request->getTransactionStatus()); + $this->assertEquals('授權成功', $this->request->getMessage()); + $this->assertEquals('2020050701', $this->request->getTransactionId()); + $this->assertEquals('2020050700000000001', $this->request->getTransactionReference()); + } +} diff --git a/tests/Message/CompletePurchaseRequestTest.php b/tests/Message/CompletePurchaseRequestTest.php new file mode 100644 index 0000000..9572939 --- /dev/null +++ b/tests/Message/CompletePurchaseRequestTest.php @@ -0,0 +1,70 @@ +request = new CompletePurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->request->initialize([ + 'CustomerId' => '80013554', + 'Str_Check' => '2b1bef9d8ab6a81e9a2739c6ecc64ef8', + ]); + } + + public function testGetCreditCardData() + { + $this->getHttpRequest()->query->replace([ + 'Send_Type' => '0', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_orderno' => '2020050701', + 'AvCode' => '012345', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + 'Invoice_No' => '12345', + 'CardLastNum' => '2222', + ]); + $this->request->setAmount('50'); + + $response = $this->request->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('授權成功', $response->getMessage()); + $this->assertEquals('1', $response->getCode()); + $this->assertEquals('2020050701', $response->getTransactionId()); + $this->assertEquals('2020050700000000001', $response->getTransactionReference()); + } + + public function testGetUnionPayData() + { + $this->getHttpRequest()->query->replace([ + 'Send_Type' => '1', + 'result' => '1', + 'ret_msg' => '授權成功', + 'OrderID' => '2020050700000000001', + 'e_orderno' => '2020050701', + 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', + ]); + $this->request->setAmount('50'); + + $response = $this->request->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertEquals('授權成功', $response->getMessage()); + $this->assertEquals('1', $response->getCode()); + $this->assertEquals('2020050701', $response->getTransactionId()); + $this->assertEquals('2020050700000000001', $response->getTransactionReference()); + } +} diff --git a/tests/Message/GetPaymentInfoRequestTest.php b/tests/Message/GetPaymentInfoRequestTest.php index 984b9c9..e8af27a 100644 --- a/tests/Message/GetPaymentInfoRequestTest.php +++ b/tests/Message/GetPaymentInfoRequestTest.php @@ -39,6 +39,7 @@ public function testGetBarcodeData() 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', ]); $this->request->setAmount('50'); + $response = $this->request->send(); $this->assertFalse($response->isSuccessful()); @@ -61,6 +62,7 @@ public function testGetVirtualAccountData() 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', ]); $this->request->setAmount('50'); + $response = $this->request->send(); $this->assertFalse($response->isSuccessful()); @@ -83,6 +85,7 @@ public function testGetCvsData() 'str_check' => 'bf577c7a76d440a797c1716aff9c01c9', ]); $this->request->setAmount('50'); + $response = $this->request->send(); $this->assertFalse($response->isSuccessful()); diff --git a/tests/Message/ResponseTest.php b/tests/Message/ResponseTest.php deleted file mode 100644 index 1fa999d..0000000 --- a/tests/Message/ResponseTest.php +++ /dev/null @@ -1,29 +0,0 @@ -getMockRequest(), ['example' => 'value', 'foo' => 'bar']); - $this->assertEquals(['example' => 'value', 'foo' => 'bar'], $response->getData()); - } - - public function testProPurchaseSuccess() - { - $this->markTestSkipped(); - - $httpResponse = $this->getMockHttpResponse('AuthorizeSuccess.txt'); - $data = json_decode($httpResponse->getBody(), true); - $response = new PurchaseResponse($this->getMockRequest(), $data); - - $this->assertTrue($response->isSuccessful()); - $this->assertEquals('1234', $response->getTransactionReference()); - $this->assertNull($response->getMessage()); - } -}