diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
new file mode 100644
index 0000000..2e4aaa7
--- /dev/null
+++ b/.github/workflows/phpunit.yml
@@ -0,0 +1,65 @@
+name: "PHPUnit tests"
+
+on:
+ pull_request:
+ push:
+ branches:
+ - "master"
+
+jobs:
+ phpunit:
+ name: "PHPUnit tests"
+
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ matrix:
+ dependencies:
+ - "highest"
+ php-version:
+ - "7.2"
+ - "7.3"
+ - "7.4"
+ - "8.0"
+ - "8.1"
+ - "8.2"
+ - "8.3"
+ - "8.4"
+
+ include:
+ - php-version: '7.2'
+ dependencies: "lowest"
+
+ steps:
+ - name: "Checkout"
+ uses: "actions/checkout@v4"
+
+ - name: "Install PHP"
+ uses: "shivammathur/setup-php@v2"
+ with:
+ coverage: "pcov"
+ php-version: "${{ matrix.php-version }}"
+ ini-values: memory_limit=-1
+ tools: composer:v2
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ # Fixes any pubkeys failure (add a `composer diagnose` step to debug if necessary)
+ - name: "Composer force self-update"
+ run: "composer self-update"
+
+ - name: "Install lowest dependencies"
+ if: ${{ matrix.dependencies == 'lowest' }}
+ run: "composer update --prefer-lowest --no-interaction --no-progress"
+
+ - name: "Install highest dependencies"
+ if: ${{ matrix.dependencies == 'highest' }}
+ run: "composer update --no-interaction --no-progress"
+
+ - name: "Tests (PHPUnit 9)"
+ if: ${{ matrix.php-version <= '8.0' }}
+ run: "vendor/bin/phpunit --configuration phpunit9.xml.dist"
+
+ - name: "Tests (PHPUnit 10+)"
+ if: ${{ matrix.php-version >= '8.1' }}
+ run: "vendor/bin/phpunit"
diff --git a/.gitignore b/.gitignore
index 8a282a5..472a3b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
composer.lock
composer.phar
phpunit.xml
+/.phpunit.result.cache
+/build
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 091cc30..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-language: php
-
-dist: trusty
-php:
- - "7.4"
- - "7.3"
- - "7.2"
- - "7.1"
- - "7.0"
- - "5.6"
-
-before_script:
- - travis_retry composer self-update
- - travis_retry composer install --no-interaction --prefer-source
-
-script:
- - vendor/bin/phpcs --standard=PSR2 src
- - vendor/bin/phpunit --verbose --coverage-clover coverage.clover
-
-after_success:
- - wget https://scrutinizer-ci.com/ocular.phar
- - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
diff --git a/composer.json b/composer.json
index 43675de..cfb24e5 100644
--- a/composer.json
+++ b/composer.json
@@ -35,29 +35,41 @@
"psr-4": { "Omnipay\\Redsys\\" : "tests/" }
},
"require": {
+ "php": "^7.2|^8.0",
"omnipay/common": "dev-address3-support"
},
"require-dev": {
"omnipay/tests": "dev-address3-support",
- "squizlabs/php_codesniffer": "^3.5"
+ "squizlabs/php_codesniffer": "^3.5",
+ "http-interop/http-factory-guzzle": "^1.1"
},
"suggest": {
"ext-openssl": "Required for hashing functions to check message signatures"
},
+ "scripts": {
+ "test": "phpunit",
+ "check-style": "phpcs -p --standard=PSR2 src/",
+ "fix-style": "phpcbf -p --standard=PSR2 src/"
+ },
"extra": {
"branch-alias": {
- "dev-master": "3.2.x-dev"
+ "dev-master": "3.3.x-dev"
}
},
"repositories": [
{
"type": "vcs",
- "url": "https://github.com/CodeDruids/omnipay-common"
+ "url": "https://github.com/PatronBase/omnipay-common"
},
{
"type": "vcs",
- "url": "https://github.com/CodeDruids/omnipay-tests"
+ "url": "https://github.com/PatronBase/omnipay-tests"
}
],
- "prefer-stable": true
+ "prefer-stable": true,
+ "config": {
+ "allow-plugins": {
+ "php-http/discovery": true
+ }
+ }
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 50647d9..21263b8 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,25 +1,30 @@
-
-
-
-
-
-
- ./tests/
-
-
-
-
- ./src
-
-
+ stopOnFailure="false">
+
+
+
+
+
+
+
+
+
+ src/
+
+
+
+
+ tests
+
+
+
+
+
diff --git a/phpunit9.xml.dist b/phpunit9.xml.dist
new file mode 100644
index 0000000..5ab568e
--- /dev/null
+++ b/phpunit9.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+ src/
+
+
+
+
+
+
+
+
+
+ tests
+
+
+
+
+
+
diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php
index 2e7b6fd..21460e1 100644
--- a/src/Message/PurchaseRequest.php
+++ b/src/Message/PurchaseRequest.php
@@ -161,7 +161,7 @@ public function getConsumerLanguage()
/**
* Set the language presented to the consumer
*
- * @param null|string|int Either the ISO 639-1 code to be converted, or the gateway's own numeric language code
+ * @param null|string|int $value The ISO 639-1 code to be converted, or the gateway's own numeric language code
*/
public function setConsumerLanguage($value)
{
@@ -177,6 +177,41 @@ public function setConsumerLanguage($value)
return $this->setParameter('consumerLanguage', $value);
}
+ public function getDirectPayment()
+ {
+ return $this->getParameter('directPayment');
+ }
+
+ /**
+ * Set the "directness" of payment
+ *
+ * Can be true (merchant initiated), false/null (customer initiated) or "MOTO" (usually call centre initiated)
+ * Invalid values will be converted to null as that's the most secure option
+ *
+ * @param null|bool|string $value
+ */
+ public function setDirectPayment($value)
+ {
+ if (is_bool($value)) {
+ // this is fine
+ } elseif (is_string($value)) {
+ if (strtoupper($value) == "TRUE") {
+ $value = true;
+ } elseif (strtoupper($value) == "FALSE") {
+ $value = false;
+ } elseif (strtoupper($value) == "MOTO") {
+ $value = "MOTO";
+ } else {
+ // something invalid
+ $value = null;
+ }
+ } else {
+ // something invalid
+ $value = null;
+ }
+ return $this->setParameter('directPayment', $value);
+ }
+
public function getHmacKey()
{
return $this->getParameter('hmacKey');
@@ -278,11 +313,11 @@ public function setUse3DS($value)
}
/**
- * Get the threeDSCompInd field
- * Corresponds to the Ds_Merchant_Emv3Ds.threeDSCompInd field in Redsys documentation.
+ * Get the threeDSCompInd field, which indicates whether the 3DSMethod has been executed
*
- * @return null|string
+ * Corresponds to the Ds_Merchant_Emv3Ds.threeDSCompInd field in Redsys documentation.
*
+ * @return null|string Y = Successfully completed, N = Completed with errors, U = 3DSMethod not executed
*/
public function getThreeDSCompInd()
{
@@ -303,11 +338,11 @@ public function setThreeDSCompInd($value)
}
/**
- * Get the threeDSInfo field
- * Corresponds to the Ds_Merchant_Emv3Ds.threeDSInfo field in Redsys documentation.
+ * Get the threeDSInfo field (the type of request)
*
- * @return null|string
+ * Corresponds to the Ds_Merchant_Emv3Ds.threeDSInfo field in Redsys documentation.
*
+ * @return null|string Possible values: CardData, AuthenticationData, ChallengeResponse
*/
public function getThreeDSInfo()
{
@@ -1507,31 +1542,6 @@ public function setBrowserColorDepth($value)
return $this->setParameter('browserColorDepth', $value);
}
- /**
- * Get the browserIP field
- *
- * Corresponds to the Ds_Merchant_Emv3Ds.browserIP field
- *
- * @return null|string
- */
- public function getBrowserIP()
- {
- return $this->getParameter('browserIP');
- }
-
- /**
- * Set the browserIP field
- *
- * Corresponds to the Ds_Merchant_Emv3Ds.browserIP field
- *
- * @param null|string $value
- * @return self
- */
- public function setBrowserIP($value)
- {
- return $this->setParameter('browserIP', $value);
- }
-
/**
* Get the browserJavaEnabled field
*
@@ -1682,31 +1692,6 @@ public function setBrowserUserAgent($value)
return $this->setParameter('browserUserAgent', $value);
}
- /**
- * Get the notificationURL field
- *
- * Corresponds to the Ds_Merchant_Emv3Ds.notificationURL field
- *
- * @return null|string
- */
- public function getNotificationURL()
- {
- return $this->getParameter('notificationURL');
- }
-
- /**
- * Set the notificationURL field
- *
- * Corresponds to the Ds_Merchant_Emv3Ds.notificationURL field
- *
- * @param null|string $value
- * @return self
- */
- public function setNotificationURL($value)
- {
- return $this->setParameter('notificationURL', $value);
- }
-
/**
* Get the basic data fields that don't require any 3DS/SCA fields
*/
@@ -1727,7 +1712,7 @@ public function getBaseData()
'Ds_Merchant_ProductDescription' => $this->getDescription(),
'Ds_Merchant_Cardholder' => $this->getCardholder(),
'Ds_Merchant_UrlOK' => $this->getReturnUrl(),
- 'Ds_Merchant_UrlKO' => $this->getReturnUrl(),
+ 'Ds_Merchant_UrlKO' => $this->getCancelUrl(),
'Ds_Merchant_MerchantName' => $this->getMerchantName(),
'Ds_Merchant_ConsumerLanguage' => $this->getConsumerLanguage(),
'Ds_Merchant_MerchantData' => $this->getMerchantData(),
@@ -1797,6 +1782,11 @@ public function getMerchantRiskData()
public function getData()
{
$data = $this->getBaseData();
+
+ if ($this->getDirectPayment() !== null) {
+ $data['Ds_Merchant_DirectPayment'] = $this->getDirectPayment();
+ }
+
if ($this->getScaExemptionIndicator() !== null) {
$data['Ds_Merchant_Excep_Sca'] = $this->getScaExemptionIndicator();
}
@@ -1831,18 +1821,16 @@ public function getData()
// required parameters for v2
'browserAcceptHeader' => $this->getBrowserAcceptHeader(),
'browserColorDepth' => $this->getBrowserColorDepth(),
- 'browserIP' => $this->getBrowserIP(),
+ 'browserIP' => $this->getClientIp(),
'browserJavaEnabled' => $this->getBrowserJavaEnabled(),
'browserLanguage' => $this->getBrowserLanguage(),
'browserScreenHeight' => $this->getBrowserScreenHeight(),
'browserScreenWidth' => $this->getBrowserScreenWidth(),
'browserTZ' => $this->getBrowserTZ(),
'browserUserAgent' => $this->getBrowserUserAgent(),
- 'notificationURL' => $this->getNotificationURL(),
+ 'notificationURL' => $this->getNotifyUrl(),
'protocolVersion' => $this->getProtocolVersion(),
- // Indicates whether the 3DSMethod has been executed. Values accepted: Y= Successfully completed, N = Completed with errors, U = 3DSMethod not executed
'threeDSCompInd' => $this->getThreeDSCompInd(),
- // Type of request. Possible values: CardData, AuthenticationData, ChallengeResponse
'threeDSInfo' => $this->getThreeDSInfo(),
'threeDSServerTransID' => $this->getTransactionId(),
// optional parameters for v2
diff --git a/tests/Message/PurchaseRequestTest.php b/tests/Message/PurchaseRequestTest.php
index a67ae5a..3470634 100644
--- a/tests/Message/PurchaseRequestTest.php
+++ b/tests/Message/PurchaseRequestTest.php
@@ -26,35 +26,37 @@ class PurchaseRequestTest extends TestCase
/** @var mixed[] */
protected $full3DSParams = [];
- public function setUp()
+ public function setUp(): void
{
$this->fullBaseParams = $this->requiredRequestParams + [
+ 'clientIp' => '192.0.0.0',
'transactionId' => '123abc',
'hmacKey' => 'Mk9m98IfEblmPfrpsawt7BmxObt98Jev',
'description' => 'My sales items',
'cardholder' => 'J Smith',
+ 'cancelUrl' => 'https://www.example.com/cancel',
'notifyUrl' => 'https://www.example.com/notify',
'returnUrl' => 'https://www.example.com/return',
'merchantName' => 'My Store',
'consumerLanguage' => 'en',
'merchantData' => 'Ref: 99zz',
+ 'directPayment' => false,
];
$this->full3DSParams = $this->fullBaseParams + [
'use3DS' => true,
'protocolVersion' => '2.1.0',
'threeDSCompInd' => 'U',
- 'threeDSInfo' => 'CardData',
+ 'threeDSInfo' => 'CardData',
'threeDSServerTransID' => '12345',
'browserAcceptHeader' => 'text/html,application',
- 'browserColorDepth' => '24',
- 'browserIP' => '192.0.0.0',
- 'browserJavaEnabled' => true,
- 'browserLanguage' => 'en-GB',
- 'browserScreenHeight' => '1000',
- 'browserScreenWidth' => '1200',
- 'browserTZ' => '2',
- 'browserUserAgent' => 'Mozilla/5.0',
+ 'browserColorDepth' => '24',
+ 'browserJavaEnabled' => true,
+ 'browserLanguage' => 'en-GB',
+ 'browserScreenHeight' => '1000',
+ 'browserScreenWidth' => '1200',
+ 'browserTZ' => '2',
+ 'browserUserAgent' => 'Mozilla/5.0',
'card' => new CreditCard([
'email' => "test@example.net",
'shippingAddress1' => "Ship 1 Test",
@@ -130,7 +132,7 @@ public function testGetBaseData()
$this->assertSame('My sales items', $data['Ds_Merchant_ProductDescription']);
$this->assertSame('J Smith', $data['Ds_Merchant_Cardholder']);
$this->assertSame('https://www.example.com/return', $data['Ds_Merchant_UrlOK']);
- $this->assertSame('https://www.example.com/return', $data['Ds_Merchant_UrlKO']);
+ $this->assertSame('https://www.example.com/cancel', $data['Ds_Merchant_UrlKO']);
$this->assertSame('My Store', $data['Ds_Merchant_MerchantName']);
$this->assertSame('002', $data['Ds_Merchant_ConsumerLanguage']);
$this->assertSame('Ref: 99zz', $data['Ds_Merchant_MerchantData']);
@@ -159,6 +161,31 @@ public function testSetConsumerLanguage()
$this->assertSame('002', $this->request->getConsumerLanguage());
}
+ public function testSetDirectPayment()
+ {
+ // starts false in base test data
+ $this->assertFalse($this->request->getDirectPayment());
+ // valid, but corrects case
+ $this->request->setDirectPayment("moto");
+ $this->assertSame('MOTO', $this->request->getDirectPayment());
+ // valid (effectively unsets)
+ $this->request->setDirectPayment(null);
+ $this->assertNull($this->request->getDirectPayment());
+ // valid
+ $this->request->setDirectPayment(true);
+ $this->assertTrue($this->request->getDirectPayment());
+ $this->request->setDirectPayment(false);
+ $this->assertFalse($this->request->getDirectPayment());
+ // valid, but converts to bool
+ $this->request->setDirectPayment("true");
+ $this->assertTrue($this->request->getDirectPayment());
+ $this->request->setDirectPayment("false");
+ $this->assertFalse($this->request->getDirectPayment());
+ // invalid, forces back to null
+ $this->request->setDirectPayment(100);
+ $this->assertNull($this->request->getDirectPayment());
+ }
+
public function testGet3DSAccountInfoData()
{
$data = $this->request->get3DSAccountInfoData();
diff --git a/tests/Message/PurchaseResponseTest.php b/tests/Message/PurchaseResponseTest.php
index 2705d5a..0f9a5ca 100644
--- a/tests/Message/PurchaseResponseTest.php
+++ b/tests/Message/PurchaseResponseTest.php
@@ -30,7 +30,7 @@ class PurchaseResponseTest extends TestCase
* 'Ds_Merchant_ConsumerLanguage' => '002',
* 'Ds_Merchant_MerchantData' => 'Ref: 99zz',
*/
- public function setUp()
+ public function setUp(): void
{
$this->response = new PurchaseResponse($this->getMockRequest(), array(
'Ds_SignatureVersion' => 'HMAC_SHA256_V1',
diff --git a/tests/Message/SecurityTest.php b/tests/Message/SecurityTest.php
index 31b9abb..0012126 100644
--- a/tests/Message/SecurityTest.php
+++ b/tests/Message/SecurityTest.php
@@ -10,13 +10,13 @@ class SecurityTest extends TestCase
protected $security;
protected $mockSecurity;
- public function setUp()
+ public function setUp(): void
{
$this->security = new Security;
$this->mockSecurity = m::mock('\Omnipay\Redsys\Message\Security');
}
- public function tearDown()
+ public function tearDown(): void
{
m::close();
}
diff --git a/tests/Message/WebservicePurchaseRequestTest.php b/tests/Message/WebservicePurchaseRequestTest.php
index 52fbfa0..3317aaa 100644
--- a/tests/Message/WebservicePurchaseRequestTest.php
+++ b/tests/Message/WebservicePurchaseRequestTest.php
@@ -10,7 +10,7 @@ class WebservicePurchaseRequestTest extends TestCase
/** @var WebservicePurchaseRequest */
private $request;
- public function setUp()
+ public function setUp(): void
{
$this->request = new WebservicePurchaseRequest($this->getHttpClient(), $this->getHttpRequest());
$this->request->initialize(
@@ -24,7 +24,7 @@ public function setUp()
'card' => new CreditCard(array(
'number' => '4548812049400004',
'expiryMonth' => '12',
- 'expiryYear' => '2020',
+ 'expiryYear' => '2030',
'cvv' => '285',
)),
@@ -50,7 +50,7 @@ public function testGetData()
$this->assertSame('0123abc', $data['DATOSENTRADA']['DS_MERCHANT_ORDER']);
$this->assertSame('4548812049400004', $data['DATOSENTRADA']['DS_MERCHANT_PAN']);
- $this->assertSame('2012', $data['DATOSENTRADA']['DS_MERCHANT_EXPIRYDATE']);
+ $this->assertSame('3012', $data['DATOSENTRADA']['DS_MERCHANT_EXPIRYDATE']);
$this->assertSame('285', $data['DATOSENTRADA']['DS_MERCHANT_CVV2']);
// $this->assertSame('My sales items', $data['DATOSENTRADA']['DS_MERCHANT_PRODUCTDESCRIPTION']);
@@ -61,7 +61,7 @@ public function testGetData()
$this->assertSame('HMAC_SHA256_V1', $data['DS_SIGNATUREVERSION']);
// signature will change if undocumented fields added
- $this->assertSame('1RPtKuPpDldIa88VBPugTqm5BWJxoUWT0503BM/U5l4=', $data['DS_SIGNATURE']);
+ $this->assertSame('hgg101IGPL2CNEJzpx2xZzSGnw/0UDqVNPUh/d52ouM=', $data['DS_SIGNATURE']);
}
public function testGetHmacKey()
diff --git a/tests/RedirectGatewayTest.php b/tests/RedirectGatewayTest.php
index 15ece9f..c932669 100644
--- a/tests/RedirectGatewayTest.php
+++ b/tests/RedirectGatewayTest.php
@@ -9,7 +9,7 @@ class RedirectGatewayTest extends GatewayTestCase
/** @var array */
protected $options;
- public function setUp()
+ public function setUp(): void
{
parent::setUp();
diff --git a/tests/WebserviceGatewayTest.php b/tests/WebserviceGatewayTest.php
index cafd389..0fc7c9c 100644
--- a/tests/WebserviceGatewayTest.php
+++ b/tests/WebserviceGatewayTest.php
@@ -10,7 +10,7 @@ class WebserviceGatewayTest extends GatewayTestCase
/** @var array */
protected $options;
- public function setUp()
+ public function setUp(): void
{
parent::setUp();