diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 23ae528e2..0e620eca4 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @msilvagarcia @cyattilakiss @Aleffio @AlexandrosMor @rikterbeek @acampos1916
+* @msilvagarcia @cyattilakiss @AlexandrosMor @acampos1916 @Aleffio @rikterbeek
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c2f8d72eb..a4b36576d 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -19,7 +19,21 @@ jobs:
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- - name: Run test suite
+ - name: Run integration tests
+ run: vendor/bin/phpunit --testsuite=integration --no-coverage
+ env:
+ INTEGRATION_USERNAME: ${{ secrets.INTEGRATION_USERNAME }}
+ INTEGRATION_PASSWORD: ${{ secrets.INTEGRATION_PASSWORD }}
+ INTEGRATION_X_API_KEY: ${{ secrets.INTEGRATION_X_API_KEY }}
+ INTEGRATION_MERCHANT_ACCOUNT: ${{ secrets.INTEGRATION_MERCHANT_ACCOUNT }}
+ INTEGRATION_SKIN_CODE: ${{ secrets.INTEGRATION_SKIN_CODE }}
+ INTEGRATION_HMAC_SIGNATURE: ${{ secrets.INTEGRATION_HMAC_SIGNATURE }}
+ INTEGRATION_STORE_PAYOUT_USERNAME: ${{ secrets.INTEGRATION_STORE_PAYOUT_USERNAME }}
+ INTEGRATION_STORE_PAYOUT_PASSWORD: ${{ secrets.INTEGRATION_STORE_PAYOUT_PASSWORD }}
+ INTEGRATION_REVIEW_PAYOUT_USERNAME: ${{ secrets.INTEGRATION_REVIEW_PAYOUT_USERNAME }}
+ INTEGRATION_REVIEW_PAYOUT_PASSWORD: ${{ secrets.INTEGRATION_REVIEW_PAYOUT_PASSWORD }}
+
+ - name: Run unit tests
run: vendor/bin/phpunit --testsuite=unit --coverage-clover build/clover.xml --log-junit build/tests-log.xml
# PHPUnit generates absolute file paths and SonarCloud expects relative file paths. This command removes the
diff --git a/phpunit.xml b/phpunit.xml
index d791e48d2..f54081198 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -30,6 +30,9 @@
./tests/Unit
+
+ ./tests/Integration
+
./tests
diff --git a/src/Adyen/Client.php b/src/Adyen/Client.php
index 7b456d07a..1169e8ad3 100644
--- a/src/Adyen/Client.php
+++ b/src/Adyen/Client.php
@@ -10,7 +10,7 @@
class Client
{
- const LIB_VERSION = "6.2.0";
+ const LIB_VERSION = "6.3.0";
const LIB_NAME = "adyen-php-api-library";
const USER_AGENT_SUFFIX = "adyen-php-api-library/";
const ENDPOINT_TEST = "https://pal-test.adyen.com";
diff --git a/src/Adyen/Util/HmacSignature.php b/src/Adyen/Util/HmacSignature.php
index f0fe8b8cd..0e9a2ed70 100644
--- a/src/Adyen/Util/HmacSignature.php
+++ b/src/Adyen/Util/HmacSignature.php
@@ -27,6 +27,7 @@
class HmacSignature
{
+ const EVENT_CODE = "eventCode";
/**
* @param string $hmacKey Can be found in Customer Area
* @param array $params The response from Adyen
@@ -69,7 +70,7 @@ private function getNotificationDataToSign($params)
// `empty` treats too many value types as empty. `isset` should prevent some of these cases.
$value = (isset($params['amount']['value'])) ? $params['amount']['value'] : "";
$currency = (!empty($params['amount']['currency'])) ? $params['amount']['currency'] : "";
- $eventCode = (!empty($params['eventCode'])) ? $params['eventCode'] : "";
+ $eventCode = (!empty($params[self::EVENT_CODE])) ? $params[self::EVENT_CODE] : "";
$success = (!empty($params['success'])) ? $params['success'] : "";
$dataToSign = array(
@@ -103,4 +104,59 @@ public function isValidNotificationHMAC($hmacKey, $params)
return $expectedSign == $merchantSign;
}
+ /**
+ * Returns true when the event code support HMAC validation
+ *
+ * @param $response
+ */
+ public function isHmacSupportedEventCode($response)
+ {
+ $eventCodes = array(
+ "ADVICE_OF_DEBIT",
+ "AUTHORISATION",
+ "AUTHORISATION_PENDING",
+ "AUTHORISE_REFERRAL",
+ "CANCELLATION",
+ "CANCEL_OR_REFUND",
+ "CAPTURE",
+ "CAPTURE_FAILED",
+ "CAPTURE_WITH_EXTERNAL_AUTH",
+ "CHARGEBACK",
+ "CHARGEBACK_REVERSED",
+ "DEACTIVATE_RECURRING",
+ "FRAUD_ONLY",
+ "FUND_TRANSFER",
+ "HANDLED_EXTERNALLY",
+ "MANUAL_REVIEW_ACCEPT",
+ "NOTIFICATION_OF_CHARGEBACK",
+ "NOTIFICATION_OF_FRAUD",
+ "OFFER_CLOSED",
+ "ORDER_OPENED",
+ "PAIDOUT_REVERSED",
+ "PAYOUT_DECLINE",
+ "PAYOUT_EXPIRE",
+ "PAYOUT_THIRDPARTY",
+ "PREARBITRATION_LOST",
+ "PREARBITRATION_WON",
+ "PROCESS_RETRY",
+ "RECURRING_CONTRACT",
+ "REFUND",
+ "REFUNDED_REVERSED",
+ "REFUND_FAILED",
+ "REFUND_WITH_DATA",
+ "REQUEST_FOR_INFORMATION",
+ "SECOND_CHARGEBACK",
+ "SUBMIT_RECURRING",
+ "VOID_PENDING_REFUND",
+ "POSTPONED_REFUND",
+ "TECHNICAL_CANCEL",
+ "AUTHORISATION_ADJUSTMENT",
+ "CANCEL_AUTORESCUE",
+ "AUTORESCUE"
+ );
+ if (array_key_exists(self::EVENT_CODE, $response) && in_array($response[self::EVENT_CODE], $eventCodes)) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/tests/BinLookupTest.php b/tests/Integration/BinLookupTest.php
similarity index 96%
rename from tests/BinLookupTest.php
rename to tests/Integration/BinLookupTest.php
index b62993aec..11e6ebd66 100644
--- a/tests/BinLookupTest.php
+++ b/tests/Integration/BinLookupTest.php
@@ -21,9 +21,10 @@
*
*/
-namespace Adyen;
+namespace Adyen\Integration;
-use Adyen\Util\Util;
+use Adyen\TestCase;
+use Adyen\Service;
class BinLookupTest extends TestCase
{
diff --git a/tests/CheckoutTest.php b/tests/Integration/CheckoutTest.php
similarity index 98%
rename from tests/CheckoutTest.php
rename to tests/Integration/CheckoutTest.php
index 5b4dbe175..4713979c3 100644
--- a/tests/CheckoutTest.php
+++ b/tests/Integration/CheckoutTest.php
@@ -21,8 +21,10 @@
*
*/
-namespace Adyen;
+namespace Adyen\Integration;
+use Adyen\TestCase;
+use Adyen\Service;
use Adyen\Util\Uuid;
class CheckoutTest extends TestCase
diff --git a/tests/CreatePaymentRequestTest.php b/tests/Integration/CreatePaymentRequestTest.php
similarity index 86%
rename from tests/CreatePaymentRequestTest.php
rename to tests/Integration/CreatePaymentRequestTest.php
index 8b662ca41..dfc86fc7e 100644
--- a/tests/CreatePaymentRequestTest.php
+++ b/tests/Integration/CreatePaymentRequestTest.php
@@ -1,6 +1,30 @@
testCreatePaymentSuccess();
@@ -33,7 +58,7 @@ public function testCancelModification()
public function testRefundModification()
{
// create a payment
- require_once __DIR__.'/CreatePaymentRequestTest.php';
+ require_once __DIR__ . '/CreatePaymentRequestTest.php';
$test = new CreatePaymentRequestTest();
$result = $test->testCreatePaymentSuccess();
@@ -63,7 +88,7 @@ public function testRefundModification()
public function testAdjustDecreaseModification()
{
// create a payment
- require_once __DIR__.'/CreatePaymentRequestTest.php';
+ require_once __DIR__ . '/CreatePaymentRequestTest.php';
$test = new CreatePaymentRequestTest();
$result = $test->testCreatePaymentSuccess();
@@ -90,7 +115,7 @@ public function testAdjustDecreaseModification()
public function testAdjustIncreaseModification()
{
// create a payment
- require_once __DIR__.'/CreatePaymentRequestTest.php';
+ require_once __DIR__ . '/CreatePaymentRequestTest.php';
$test = new CreatePaymentRequestTest();
$result = $test->testCreatePaymentSuccess();
diff --git a/tests/PayoutThirdPartyTest.php b/tests/Integration/PayoutThirdPartyTest.php
similarity index 96%
rename from tests/PayoutThirdPartyTest.php
rename to tests/Integration/PayoutThirdPartyTest.php
index 4e5664da6..9f3f16294 100644
--- a/tests/PayoutThirdPartyTest.php
+++ b/tests/Integration/PayoutThirdPartyTest.php
@@ -21,10 +21,23 @@
*
*/
-namespace Adyen;
+namespace Adyen\Integration;
+use Adyen\TestCase;
+use Adyen\Service;
+
+/**
+ * Class PayoutThirdPartyTest
+ *
+ * @package Adyen\Integration
+ */
class PayoutThirdPartyTest extends TestCase
{
+ protected function setUp(): void
+ {
+ $this->markTestIncomplete('Configure Payout accounts');
+ }
+
public function testStoreDetailAndSubmitPayoutThirdPartyMissingReference()
{
// initialize client
@@ -326,7 +339,7 @@ public function testConfirmPayoutThirdPartyInvalidReference()
// check if exception is correct
$this->assertEquals('Adyen\AdyenException', get_class($e));
$this->assertEquals(
- 'Invalid Request: Original pspReference is invalid for this environment!',
+ 'Original pspReference required for this operation',
$e->getMessage()
);
}
@@ -367,7 +380,7 @@ public function testDeclinePayoutThirdPartySuccess()
public function testDeclinePayoutThirdPartyInvalidReference()
{
$this->expectException('Adyen\AdyenException');
- $this->expectExceptionMessage('Invalid Request: Original pspReference is invalid for this environment!');
+ $this->expectExceptionMessage('Original pspReference required for this operation');
// initialize client
$client = $this->createReviewPayoutClient();
diff --git a/tests/PosPaymentTest.php b/tests/Integration/PosPaymentTest.php
similarity index 94%
rename from tests/PosPaymentTest.php
rename to tests/Integration/PosPaymentTest.php
index 6634cf726..7aeafce67 100644
--- a/tests/PosPaymentTest.php
+++ b/tests/Integration/PosPaymentTest.php
@@ -1,8 +1,30 @@
settings = $this->loadConfigIni();
+ $this->settings = $this->loadConfig();
$this->merchantAccount = $this->getMerchantAccount();
$this->skinCode = $this->getSkinCode();
$this->hmacSignature = $this->getHmacSignature();
@@ -252,6 +273,25 @@ protected function getPOIID()
return $settings['POIID'];
}
+ protected function loadConfig()
+ {
+ if (file_exists($this->getTestFilePath())) {
+ return $this->loadConfigIni();
+ }
+ return array(
+ 'username' => getenv('INTEGRATION_USERNAME'),
+ 'password' => getenv('INTEGRATION_PASSWORD'),
+ 'x-api-key' => getenv('INTEGRATION_X_API_KEY'),
+ 'merchantAccount' => getenv('INTEGRATION_MERCHANT_ACCOUNT'),
+ 'skinCode' => getenv('INTEGRATION_SKIN_CODE'),
+ 'hmacSignature' => getenv('INTEGRATION_HMAC_SIGNATURE'),
+ 'storePayoutUsername' => getenv('INTEGRATION_STORE_PAYOUT_USERNAME'),
+ 'storePayoutPassword' => getenv('INTEGRATION_STORE_PAYOUT_PASSWORD'),
+ 'reviewPayoutUsername' => getenv('INTEGRATION_REVIEW_PAYOUT_USERNAME'),
+ 'reviewPayoutPassword' => getenv('INTEGRATION_REVIEW_PAYOUT_PASSWORD'),
+ );
+ }
+
/**
* Loads the settings into and array from the config/test.ini file
*
@@ -259,7 +299,7 @@ protected function getPOIID()
*/
protected function loadConfigIni()
{
- return parse_ini_file(__DIR__ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'test.ini', true);
+ return parse_ini_file($this->getTestFilePath(), true);
}
@@ -313,4 +353,12 @@ protected function getMethod($class, $name)
$method->setAccessible(true);
return $method;
}
+
+ /**
+ * @return string
+ */
+ protected function getTestFilePath()
+ {
+ return __DIR__ . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'test.ini';
+ }
}
diff --git a/tests/Unit/Util/HmacSignatureTest.php b/tests/Unit/Util/HmacSignatureTest.php
index 4a6baa4ea..a2e41abe7 100644
--- a/tests/Unit/Util/HmacSignatureTest.php
+++ b/tests/Unit/Util/HmacSignatureTest.php
@@ -127,4 +127,26 @@ public function testHmacSignatureEscaping()
$this->fail('Unexpected exception');
}
}
+
+ public function testIsHmacSupportedEventCode()
+ {
+ $params = json_decode('{
+ "pspReference": "7914073381342284",
+ "merchantAccountCode": "TestMerchant",
+ "merchantReference": "TestPayment-1407325143704",
+ "amount": {
+ "value": 0,
+ "currency": "EUR"
+ },
+ "eventCode": "AUTHORISATION",
+ "success": "true"
+ }', true);
+ $hmac = new HmacSignature();
+ try {
+ $hmacSupportedEventCode = $hmac->isHmacSupportedEventCode($params);
+ $this->assertTrue($hmacSupportedEventCode);
+ } catch (AdyenException $e) {
+ $this->fail('Unexpected exception');
+ }
+ }
}
diff --git a/tests/config/test.ini b/tests/config/test.ini.sample
similarity index 81%
rename from tests/config/test.ini
rename to tests/config/test.ini.sample
index b79a75dbe..f1946c6d9 100644
--- a/tests/config/test.ini
+++ b/tests/config/test.ini.sample
@@ -5,9 +5,8 @@ merchantAccount = YOUR MERCHANT ACCOUNT
skinCode = YOUR SKIN CODE
hmacSignature = YOUR HMAC SIGNATURE
x-api-key = YOUR X-API KEY
-POIID = UNIQUETERMINALID
storePayoutUsername = YOUR STORE PAYOUT USERNAME
storePayoutPassword = "YOUR STORE PAYOUT PASSWORD"
reviewPayoutUsername = YOUR REVIEW PAYOUT USERNAME
-reviewPayoutPassword = "YOUR REVIEW PAYOUT PASSWORD"
\ No newline at end of file
+reviewPayoutPassword = "YOUR REVIEW PAYOUT PASSWORD"