diff --git a/.gitignore b/.gitignore index c3da1957e..a0787251a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ composer.lock # ignore Mac OS X file -.DS_Store \ No newline at end of file +.DS_Store + +# ignore PhpStorm .idea folder +.idea \ No newline at end of file diff --git a/src/Adyen/Service/Payout.php b/src/Adyen/Service/Payout.php new file mode 100644 index 000000000..fc54291b1 --- /dev/null +++ b/src/Adyen/Service/Payout.php @@ -0,0 +1,67 @@ +_confirm = new \Adyen\Service\ResourceModel\Payout\Confirm($this); + $this->_decline = new \Adyen\Service\ResourceModel\Payout\Decline($this); + $this->_storeDetailsAndSubmit = new \Adyen\Service\ResourceModel\Payout\StoreDetailsAndSubmit($this); + $this->_submit = new \Adyen\Service\ResourceModel\Payout\Submit($this); + $this->_confirmThirdParty = new \Adyen\Service\ResourceModel\Payout\ThirdParty\ConfirmThirdParty($this); + $this->_declineThirdParty = new \Adyen\Service\ResourceModel\Payout\ThirdParty\DeclineThirdParty($this); + $this->_storeDetailsAndSubmitThirdParty = new \Adyen\Service\ResourceModel\Payout\ThirdParty\StoreDetailsAndSubmitThirdParty($this); + $this->_submitThirdParty = new \Adyen\Service\ResourceModel\Payout\ThirdParty\SubmitThirdParty($this); + + } + + public function confirm($params) { + $result = $this->_confirm->request($params); + return $result; + } + public function decline($params) { + $result = $this->_decline->request($params); + return $result; + } + public function storeDetailsAndSubmit($params) { + $result = $this->_storeDetailsAndSubmit->request($params); + return $result; + } + public function submit($params) { + $result = $this->_submit->request($params); + return $result; + } + public function confirmThirdParty($params) { + $result = $this->_confirmThirdParty->request($params); + return $result; + } + public function declineThirdParty($params) { + $result = $this->_declineThirdParty->request($params); + return $result; + } + public function storeDetailsAndSubmitThirdParty($params) { + $result = $this->_storeDetailsAndSubmitThirdParty->request($params); + return $result; + } + public function submitThirdParty($params) { + $result = $this->_submitThirdParty->request($params); + return $result; + } + + + +} diff --git a/src/Adyen/Service/ResourceModel/Payout/Confirm.php b/src/Adyen/Service/ResourceModel/Payout/Confirm.php new file mode 100644 index 000000000..f1bec89d0 --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/Confirm.php @@ -0,0 +1,20 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/confirm'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/Decline.php b/src/Adyen/Service/ResourceModel/Payout/Decline.php new file mode 100644 index 000000000..cfb64fb00 --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/Decline.php @@ -0,0 +1,20 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/decline'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/StoreDetailsAndSubmit.php b/src/Adyen/Service/ResourceModel/Payout/StoreDetailsAndSubmit.php new file mode 100644 index 000000000..5c777b2de --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/StoreDetailsAndSubmit.php @@ -0,0 +1,25 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/storeDetailAndSubmit'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/Submit.php b/src/Adyen/Service/ResourceModel/Payout/Submit.php new file mode 100644 index 000000000..97a5e6ba6 --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/Submit.php @@ -0,0 +1,26 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/submit'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/ThirdParty/ConfirmThirdParty.php b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/ConfirmThirdParty.php new file mode 100644 index 000000000..7c37d1ada --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/ConfirmThirdParty.php @@ -0,0 +1,20 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/confirmThirdParty'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/ThirdParty/DeclineThirdParty.php b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/DeclineThirdParty.php new file mode 100644 index 000000000..d83c03179 --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/DeclineThirdParty.php @@ -0,0 +1,20 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/declineThirdParty'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/ThirdParty/StoreDetailsAndSubmitThirdParty.php b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/StoreDetailsAndSubmitThirdParty.php new file mode 100644 index 000000000..53d714704 --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/StoreDetailsAndSubmitThirdParty.php @@ -0,0 +1,28 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/storeDetailAndSubmitThirdParty'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/src/Adyen/Service/ResourceModel/Payout/ThirdParty/SubmitThirdParty.php b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/SubmitThirdParty.php new file mode 100644 index 000000000..6319670ce --- /dev/null +++ b/src/Adyen/Service/ResourceModel/Payout/ThirdParty/SubmitThirdParty.php @@ -0,0 +1,26 @@ +_endpoint = $service->getClient()->getConfig()->get('endpoint') . '/pal/servlet/Payout/' . $service->getClient()->getApiVersion() . '/submitThirdParty'; + parent::__construct($service, $this->_endpoint, $this->_requiredFields); + } + +} \ No newline at end of file diff --git a/tests/DirectoryLookupTest.php b/tests/DirectoryLookupTest.php index d800139c6..2d4ec3923 100644 --- a/tests/DirectoryLookupTest.php +++ b/tests/DirectoryLookupTest.php @@ -13,9 +13,10 @@ class DirectoryLookupTest extends TestCase { + public function testDirectoryLookup() { - + $this->_needSkinCode(); // initialize client $client = $this->createClient(); @@ -72,11 +73,10 @@ public function testDirectoryLookupEmptyParameters() // initialize service $service = new Service\DirectoryLookup($client); - $error = null; + $e = null; try { $result = $service->directoryLookup(""); } catch (\Exception $e) { - $error = $e; } $this->assertEquals('Adyen\AdyenException', get_class($e)); @@ -87,6 +87,7 @@ public function testDirectoryLookupEmptyParameters() public function testDirectoryLookupFailed() { + $this->_needSkinCode(); // initialize client $client = $this->createClient(); @@ -113,11 +114,10 @@ public function testDirectoryLookupFailed() // convert the result into an array $params = json_decode($json, true); - $error = null; + $e = null; try { $result = $service->directoryLookup($params); } catch (\Exception $e) { - $error = $e; } $this->assertEquals('Adyen\AdyenException', get_class($e)); diff --git a/tests/PayoutThirdPartyTest.php b/tests/PayoutThirdPartyTest.php new file mode 100644 index 000000000..d80e86fe8 --- /dev/null +++ b/tests/PayoutThirdPartyTest.php @@ -0,0 +1,380 @@ +createPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "bank": { + "iban": "FR14 2004 1010 0505 0001 3M02 606", + "ownerName": "John Smith", + "countryCode": "FR" + }, + "amount": { + "value": 1500, + "currency": "EUR" + }, + "recurring": { + "contract": "PAYOUT" + }, + "shopperEmail": "john.smith@test.com", + "shopperReference": "johnsmithuniqueid", + "merchantAccount": "' . $this->_merchantAccount .'" + }'; + + $params = json_decode($json, true); + $e = null; + + try { + $result = $service->storeDetailsAndSubmitThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // check if exception is correct + $this->assertEquals('Adyen\AdyenException', get_class($e)); + $this->assertEquals('Missing the following fields: reference', $e->getMessage()); + + } + + public function testStoreDetailAndSubmitPayoutThirdPartyBadPaymentMethod() + { + // initialize client + $client = $this->createPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "card": { + "number": "4111111111111111", + "expiryMonth": "08", + "expiryYear": "2018", + "cvc": "737", + "holderName": "John Smith" + }, + "amount": { + "value": 1500, + "currency": "EUR" + }, + "reference": "payout-test", + "recurring": { + "contract": "PAYOUT" + }, + "shopperEmail": "john.smith@test.com", + "shopperReference": "johnsmithuniqueid", + "merchantAccount": "' . $this->_merchantAccount .'" + }'; + + $params = json_decode($json, true); + $e = null; + try { + $result = $service->storeDetailsAndSubmitThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // check if exception is correct + $this->assertEquals('Adyen\AdyenException', get_class($e)); + $this->assertEquals('Missing the following fields: bank.iban,bank.ownerName,bank.countryCode', $e->getMessage()); + } + + public function testStoreDetailAndSubmitPayoutThirdPartyInvalidIban() + { + // initialize client + $client = $this->createPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "bank": { + "iban": "4111111111111111", + "ownerName": "John Smith", + "countryCode": "FR" + }, + "amount": { + "value": 1500, + "currency": "EUR" + }, + "reference": "payout-test", + "recurring": { + "contract": "PAYOUT" + }, + "shopperEmail": "john.smith@test.com", + "shopperReference": "johnsmithuniqueid", + "merchantAccount": "' . $this->_merchantAccount .'" + }'; + + $params = json_decode($json, true); + $e = null; + try { + $result = $service->storeDetailsAndSubmitThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + + // check if exception is correct + $this->assertEquals('Adyen\AdyenException', get_class($e)); + $this->assertEquals('Invalid iban', $e->getMessage()); + } + + public function testStoreDetailAndSubmitPayoutThirdPartySuccess() + { + // initialize client + $client = $this->createPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "bank": { + "iban": "FR14 2004 1010 0505 0001 3M02 606", + "ownerName": "John Smith", + "countryCode": "FR" + }, + "amount": { + "value": 1500, + "currency": "EUR" + }, + "reference": "payout-test", + "recurring": { + "contract": "PAYOUT" + }, + "shopperEmail": "john.smith@test.com", + "shopperReference": "johnsmithuniqueid", + "merchantAccount": "' . $this->_merchantAccount .'" + }'; + + $params = json_decode($json, true); + + try { + $result = $service->storeDetailsAndSubmitThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // must exists + $this->assertTrue(isset($result['resultCode'])); + + // Assert + $this->assertEquals('[payout-submit-received]', $result['resultCode']); + + // return the result so this can be used in other test cases + return $result; + + } + + public function testSubmitPayoutThirdPartySuccess() + { + // initialize client + $client = $this->createPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "amount": { + "value": 1500, + "currency": "EUR" + }, + "reference": "payout-test", + "recurring": { + "contract": "PAYOUT" + }, + "shopperEmail": "john.smith@test.com", + "shopperReference": "johnsmithuniqueid", + "selectedRecurringDetailReference": "LATEST", + "merchantAccount": "' . $this->_merchantAccount .'" + }'; + + $params = json_decode($json, true); + + try { + $result = $service->submitThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // must exists + $this->assertTrue(isset($result['resultCode'])); + + // Assert + $this->assertEquals('[payout-submit-received]', $result['resultCode']); + + // return the result so this can be used in other test cases + return $result; + } + + public function testSubmitPayoutThirdPartyBadRecurringDetailReference() + { + // initialize client + $client = $this->createPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "amount": { + "value": 1500, + "currency": "EUR" + }, + "reference": "payout-test", + "recurring": { + "contract": "PAYOUT" + }, + "shopperEmail": "john.smith@test.com", + "shopperReference": "johnsmithuniqueid", + "selectedRecurringDetailReference": "1234", + "merchantAccount": "' . $this->_merchantAccount .'" + }'; + + $params = json_decode($json, true); + + $e = null; + try { + $result = $service->submitThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // check if exception is correct + $this->assertEquals('Adyen\AdyenException', get_class($e)); + $this->assertEquals('PaymentDetail not found', $e->getMessage()); + } + + public function testConfirmPayoutThirdPartySuccess() + { + // initialize client + $client = $this->createReviewPayoutClient(); + + $submitted_payout = $this->testSubmitPayoutThirdPartySuccess(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "merchantAccount": "' . $this->_merchantAccount .'", + "originalReference": '.$submitted_payout['pspReference'].' + }'; + + $params = json_decode($json, true); + + try { + $result = $service->confirmThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // must exists + $this->assertTrue(isset($result['pspReference'])); + + // Assert + $this->assertEquals('[payout-confirm-received]', $result['response']); + + // return the result so this can be used in other test cases + return $result; + } + + public function testConfirmPayoutThirdPartyInvalidReference() + { + // initialize client + $client = $this->createReviewPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "merchantAccount": "' . $this->_merchantAccount .'", + "originalReference": "" + }'; + + $params = json_decode($json, true); + $e = null; + try { + $result = $service->confirmThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // check if exception is correct + $this->assertEquals('Adyen\AdyenException', get_class($e)); + $this->assertEquals('Missing the following values: originalReference', $e->getMessage()); + } + + public function testDeclinePayoutThirdPartySuccess() + { + // initialize client + $client = $this->createReviewPayoutClient(); + + $submitted_payout = $this->testSubmitPayoutThirdPartySuccess(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "merchantAccount": "' . $this->_merchantAccount .'", + "originalReference": '.$submitted_payout['pspReference'].' + }'; + + $params = json_decode($json, true); + + try { + $result = $service->declineThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // must exists + $this->assertTrue(isset($result['pspReference'])); + + // Assert + $this->assertEquals('[payout-decline-received]', $result['response']); + + // return the result so this can be used in other test cases + return $result; + } + + public function testDeclinePayoutThirdPartyInvalidReference() + { + // initialize client + $client = $this->createReviewPayoutClient(); + + // initialize service + $service = new Service\Payout($client); + + $json = '{ + "merchantAccount": "' . $this->_merchantAccount .'", + "originalReference": "" + }'; + + $params = json_decode($json, true); + $e = null; + try { + $result = $service->declineThirdParty($params); + } catch (\Exception $e) { + $this->validateApiPermission($e); + } + + // check if exception is correct + $this->assertEquals('Adyen\AdyenException', get_class($e)); + $this->assertEquals('Missing the following values: originalReference', $e->getMessage()); + } + +} diff --git a/tests/TestCase.php b/tests/TestCase.php index c5595e892..ab6c93e53 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -17,42 +17,116 @@ public function __construct() } - /** - * Mock client - * - * @return Adyen_Client - */ - protected function createClient() - { - // load settings from .ini file - $settings = $this->_loadConfigIni(); - - // validate username, password and MERCHANTAccount - - if(isset($settings['username']) && isset($settings['password'])) { - - if($settings['username'] == "YOUR USERNAME" - || $settings['username'] == "" - || $settings['password'] == "YOUR PASSWORD" - || $settings['password'] == "") - { - $client = new \Adyen\Client(); - $client->setApplicationName("My Test Application"); - $client->setEnvironment(\Adyen\Environment::TEST); - $this->_skipTest(); - return $client; - } else { - $client = new \Adyen\Client(); - $client->setApplicationName("My Test Application"); - $client->setUsername($settings['username']); - $client->setPassword($settings['password']); - $client->setEnvironment(\Adyen\Environment::TEST); - return $client; - } - } else { - $this->_skipTest(); - } - } + /** + * Mock client + * + * @return \Adyen\Client + */ + protected function createClient() + { + // load settings from .ini file + $settings = $this->_loadConfigIni(); + + // validate username, password and MERCHANTAccount + + if(isset($settings['username']) && isset($settings['password'])) { + + if($settings['username'] == "YOUR USERNAME" + || $settings['username'] == "" + || $settings['password'] == "YOUR PASSWORD" + || $settings['password'] == "") + { + $client = new \Adyen\Client(); + $client->setApplicationName("My Test Application"); + $client->setEnvironment(\Adyen\Environment::TEST); + $this->_skipTest("Skipped the test. Configure your WebService Username and Password in the config"); + return $client; + } else { + $client = new \Adyen\Client(); + $client->setApplicationName("My Test Application"); + $client->setUsername($settings['username']); + $client->setPassword($settings['password']); + $client->setEnvironment(\Adyen\Environment::TEST); + return $client; + } + } else { + $this->_skipTest("Skipped the test. Configure your WebService Username and Password in the config"); + } + } + + /** + * Mock client for payout + * + * @return \Adyen\Client + */ + protected function createPayoutClient() + { + // load settings from .ini file + $settings = $this->_loadConfigIni(); + + // validate username, password and MERCHANTAccount + + if(isset($settings['storePayoutUsername']) && isset($settings['storePayoutPassword'])) { + + if($settings['storePayoutUsername'] == "YOUR STORE PAYOUT USERNAME" + || $settings['storePayoutUsername'] == "" + || $settings['storePayoutPassword'] == "YOUR STORE PAYOUT PASSWORD" + || $settings['storePayoutPassword'] == "") + { + $client = new \Adyen\Client(); + $client->setApplicationName("My Test Application"); + $client->setEnvironment(\Adyen\Environment::TEST); + $this->_skipTest("Skipped the test. Configure your WebService Payout Username and Password in the config"); + return $client; + } else { + $client = new \Adyen\Client(); + $client->setApplicationName("My Test Application"); + $client->setUsername($settings['storePayoutUsername']); + $client->setPassword($settings['storePayoutPassword']); + $client->setEnvironment(\Adyen\Environment::TEST); + return $client; + } + } else { + $this->_skipTest("Skipped the test. Configure your WebService Payout Username and Password in the config"); + } + } + + /** + * Mock client for reviewing payout + * + * @return \Adyen\Client + */ + protected function createReviewPayoutClient() + { + // load settings from .ini file + $settings = $this->_loadConfigIni(); + + // validate username, password and MERCHANTAccount + + if(isset($settings['reviewPayoutUsername']) && isset($settings['reviewPayoutPassword'])) { + + if($settings['reviewPayoutUsername'] == "YOUR REVIEW PAYOUT USERNAME" + || $settings['reviewPayoutUsername'] == "" + || $settings['reviewPayoutPassword'] == "YOUR REVIEW PAYOUT PASSWORD" + || $settings['reviewPayoutPassword'] == "") + { + $client = new \Adyen\Client(); + $client->setApplicationName("My Test Application"); + $client->setEnvironment(\Adyen\Environment::TEST); + $this->_skipTest("Skipped the test. Configure your WebService ReviewPayout Username and Password in the config"); + return $client; + } else { + $client = new \Adyen\Client(); + $client->setApplicationName("My Test Application"); + $client->setUsername($settings['reviewPayoutUsername']); + $client->setPassword($settings['reviewPayoutPassword']); + $client->setEnvironment(\Adyen\Environment::TEST); + return $client; + } + } else { + $this->_skipTest("Skipped the test. Configure your WebService ReviewPayout Username and Password in the config"); + } + } protected function createClientWithMerchantAccount() @@ -63,7 +137,7 @@ protected function createClientWithMerchantAccount() $settings = $this->_loadConfigIni(); if(!isset($settings['merchantAccount']) || $settings['merchantAccount'] == 'YOUR MERCHANTACCOUNT') { - $this->_skipTest(); + $this->_skipTest("Skipped the test. Configure your MerchantAccount in the config"); return null; } @@ -86,7 +160,7 @@ protected function getSkinCode() { $settings = $this->_loadConfigIni(); - if(!isset($settings['skinCode']) || $settings['merchantAccount'] == 'YOUR SKINCODE') { + if(!isset($settings['skinCode']) || $settings['skinCode'] == 'YOUR SKIN CODE') { return null; } @@ -110,11 +184,17 @@ protected function _loadConfigIni() } - protected function _skipTest() + protected function _skipTest($msg) { - $this->markTestSkipped("Skipped the test. Configure your WebService Username, Password and MerchantAccount in the config"); + $this->markTestSkipped($msg); } + protected function _needSkinCode() { + if (!$this->_skinCode) { + $this->_skipTest("Skipped the test. Configure your SkinCode in the config"); + } + } + public function validateApiPermission($e) { // it is possible you do not have permission to use full API then switch over to CSE diff --git a/tests/config/test.ini b/tests/config/test.ini index 78da9a701..928280fec 100644 --- a/tests/config/test.ini +++ b/tests/config/test.ini @@ -4,3 +4,8 @@ password = "YOUR PASSWORD" merchantAccount = YOUR MERCHANT ACCOUNT skinCode = YOUR SKIN CODE hmacSignature = YOUR HMAC SIGNATURE + +storePayoutUsername = YOUR STORE PAYOUT USERNAME +storePayoutPassword = "YOUR STORE PAYOUT PASSWORD" +reviewPayoutUsername = YOUR REVIEW PAYOUT USERNAME +reviewPayoutPassword = "YOUR REVIEW PAYOUT PASSWORD"