diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..7133d483
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,9 @@
+# Ignore all test and documentation with "export-ignore".
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.travis.yml export-ignore
+/phpunit.xml.dist export-ignore
+/.scrutinizer.yml export-ignore
+/update_currencies.php export-ignore
+/tests export-ignore
+/docs export-ignore
\ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..0d77ee1a
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: [barryvdh]
diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
new file mode 100644
index 00000000..f25a1831
--- /dev/null
+++ b/.github/workflows/phpunit.yml
@@ -0,0 +1,59 @@
+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
+
+ - 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 9ab0cfa4..73418ea9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+build
/vendor
composer.lock
composer.phar
@@ -5,4 +6,5 @@ phpunit.xml
.directory
reports/
documents/
-.idea
\ No newline at end of file
+.idea
+.phpunit.result.cache
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index abb187d5..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-language: php
-
-php:
- - 5.3
- - 5.4
- - 5.5
- - 5.6
- - 7.0
- - 7.1
- - hhvm
-
-# This triggers builds to run on the new TravisCI infrastructure.
-# See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/
-sudo: false
-
-## Cache composer
-cache:
- directories:
- - $HOME/.composer/cache
-
-env:
- global:
- - setup=basic
-
-matrix:
- include:
- - php: 5.3
- env: setup=lowest
- - php: 5.5
- env: setup=lowest
-
-install:
- - if [[ $setup = 'basic' ]]; then travis_retry composer install --prefer-dist --no-interaction; fi
- - if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable; fi
-
-script: vendor/bin/phpcs --standard=PSR2 src && vendor/bin/phpunit --coverage-text
diff --git a/LICENSE b/LICENSE
index d49d0a9d..23d85a3b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012-2013 Adrian Macneil
+Copyright (c) Adrian Macneil
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
index 5c6f4127..130d776b 100644
--- a/README.md
+++ b/README.md
@@ -2,22 +2,48 @@
**Core components for the Omnipay PHP payment processing library**
-[](https://travis-ci.org/thephpleague/omnipay-common)
-[](https://packagist.org/packages/omnipay/common)
-[](https://packagist.org/packages/omnipay/common)
+[](https://github.com/thephpleague/omnipay-common/actions/workflows/phpunit.yml)
+[![Latest Version on Packagist][ico-version]][link-packagist]
+[![Software License][ico-license]](LICENSE)
+[![Total Downloads][ico-downloads]][link-downloads]
[Omnipay](https://github.com/thephpleague/omnipay) is a framework agnostic, multi-gateway payment
-processing library for PHP 5.3+. This package implements common classes required by Omnipay.
+processing library for PHP. This package implements common classes required by Omnipay.
+
+## Documentation
+
+Please see [https://omnipay.thephpleague.com/](https://omnipay.thephpleague.com/) for the installation & usage documentation.
+
+## Change log
+
+Please see [UPGRADE](UPGRADE.md) for more information on how to upgrade to the latest version.
## Support
If you are having general issues with Omnipay, we suggest posting on
-[Stack Overflow](http://stackoverflow.com/). Be sure to add the
-[omnipay tag](http://stackoverflow.com/questions/tagged/omnipay) so it can be easily found.
+[Stack Overflow](https://stackoverflow.com/). Be sure to add the
+[omnipay tag](https://stackoverflow.com/questions/tagged/omnipay) so it can be easily found.
-If you want to keep up to date with release anouncements, discuss ideas for the project,
+If you want to keep up to date with release announcements, discuss ideas for the project,
or ask more detailed questions, there is also a [mailing list](https://groups.google.com/forum/#!forum/omnipay) which
you can subscribe to.
If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/thephpleague/omnipay-common/issues),
or better yet, fork the library and submit a pull request.
+
+
+## Security
+
+If you discover any security related issues, please email barryvdh@gmail.com instead of using the issue tracker.
+
+
+## License
+
+The MIT License (MIT). Please see [License File](LICENSE) for more information.
+
+[ico-version]: https://img.shields.io/packagist/v/omnipay/common.svg?style=flat
+[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat
+[ico-downloads]: https://img.shields.io/packagist/dt/omnipay/common.svg?style=flat
+
+[link-packagist]: https://packagist.org/packages/omnipay/common
+[link-downloads]: https://packagist.org/packages/omnipay/common
diff --git a/UPGRADE.md b/UPGRADE.md
new file mode 100644
index 00000000..973cdff2
--- /dev/null
+++ b/UPGRADE.md
@@ -0,0 +1,62 @@
+## Upgrade apps from 2.x to 3.x
+ - The `redirect()` method no longer calls `exit()` after sending the content. This is up to the developer now.
+ - It is now possible to use `setAmountInteger(integer $value)` and `setMoney(Money $money)`
+ - HTTPPlug is used. Guzzle will be installed when using `omnipay/omnipay`, otherwise you need to require your own implementation (see http://docs.php-http.org/en/latest/clients.html)
+ - The package is renamed from `omnipay/omnipay` to `league/omnipay` and no longer installs all gateways by default.
+## Upgrade Gateways from 2.x to 3.x
+
+The primary difference is the HTTP Client. We are now using HTTPlug (http://httplug.io/) but rely on our own interface.
+
+### Breaking
+- Change typehint from Guzzle ClientInterface to `Omnipay\Common\Http\ClientInterface`
+- `$client->get('..')`/`$client->post('..')` etc are removed, you can call `$client->request('GET', '')`.
+- No need to call `$request->send()`, requests are sent directly.
+- Instead of `$client->createRequest(..)` you can create+send the request directly with `$client->request(..)`.
+- When sending a JSON body, convert the body to a string with `json_encode()` and set the correct Content-Type.
+- The response is a PSR-7 Response object. You can call `$response->getBody()->getContents()` to get the body as a string.
+- `$response->json()` and `$response->xml()` are gone, but you can implement the logic directly.
+- An HTTP Client is no longer added by default by `omnipay/common`, but `omnipay/omnipay` will add Guzzle.
+Gateways should not rely on Guzzle or other clients directly.
+- `$body` should be a string (eg. `http_build_query($data)` or `json_encode($data)` instead of just `$data`).
+- The `$headers` parameters should be an `array` (not `null`, but can be empty)
+
+Examples:
+```php
+// V2 XML:
+ $response = $this->httpClient->post($this->endpoint, null, $data)->send();
+ $result = $httpResponse->xml();
+
+// V3 XML:
+ $response = $this->httpClient->request('POST', $this->endpoint, [], http_build_query($data));
+ $result = simplexml_load_string($httpResponse->getBody()->getContents());
+```
+
+```php
+// Example JSON request:
+
+ $response = $this->httpClient->request('POST', $this->endpoint, [
+ 'Accept' => 'application/json',
+ 'Content-Type' => 'application/json',
+ ], json_encode($data));
+
+ $result = json_decode($response->getBody()->getContents(), true);
+```
+
+#### Testing
+
+PHPUnit is upgraded to PHPUnit 6. Common issues:
+
+- `setExpectedException()` is removed
+```php
+// PHPUnit 5:
+$this->setExpectedException($class, $message);
+
+// PHPUnit 6:
+$this->expectException($class);
+$this->expectExceptionMessage($message);
+```
+
+- Tests that do not perform any assertions, will be marked as risky. This can be avoided by annotating them with ` @doesNotPerformAssertions`
+
+- You should remove the `Mockery\Adapter\Phpunit\TestListener` in phpunit.xml.dist
+
diff --git a/composer.json b/composer.json
index 320d2145..be27a33e 100644
--- a/composer.json
+++ b/composer.json
@@ -17,62 +17,64 @@
"name": "Adrian Macneil",
"email": "adrian@adrianmacneil.com"
},
+ {
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
+ },
+ {
+ "name": "Jason Judge",
+ "email": "jason.judge@consil.co.uk"
+ },
+ {
+ "name": "Del"
+ },
{
"name": "Omnipay Contributors",
"homepage": "https://github.com/thephpleague/omnipay-common/contributors"
}
],
"autoload": {
- "psr-0": { "Omnipay\\Common\\" : "src/" },
- "classmap": ["src/Omnipay/Omnipay.php"]
+ "psr-4": { "Omnipay\\Common\\" : "src/Common" },
+ "classmap": ["src/Omnipay.php"]
+ },
+ "autoload-dev": {
+ "psr-4": { "Omnipay\\Common\\" : "tests/Common" },
+ "classmap": ["tests/OmnipayTest.php"]
},
"require": {
- "php": ">=5.3.2",
- "guzzle/guzzle": "~3.9",
- "symfony/http-foundation": "~2.1|~3.0"
+ "php": "^7.2|^8",
+ "php-http/client-implementation": "^1",
+ "php-http/message": "^1.5",
+ "php-http/message-factory": "^1.1",
+ "php-http/discovery": "^1.14",
+ "symfony/http-foundation": "^2.1|^3|^4|^5|^6|^7",
+ "moneyphp/money": "^3.1|^4.0.3"
},
"require-dev": {
- "omnipay/tests": "~2.0",
- "squizlabs/php_codesniffer": "~1.5"
+ "omnipay/tests": "^4.1",
+ "php-http/mock-client": "^1.6",
+ "php-http/guzzle7-adapter": "^1",
+ "squizlabs/php_codesniffer": "^3.8.1",
+ "http-interop/http-factory-guzzle": "^1.1"
},
"extra": {
"branch-alias": {
- "dev-master": "2.5.x-dev"
- },
- "gateways": [
- "AuthorizeNet_AIM",
- "AuthorizeNet_SIM",
- "Buckaroo_CreditCard",
- "Buckaroo_Ideal",
- "Buckaroo_PayPal",
- "CardSave",
- "Coinbase",
- "Dummy",
- "Eway_Rapid",
- "FirstData_Connect",
- "GoCardless",
- "Manual",
- "Migs_ThreeParty",
- "Migs_TwoParty",
- "Mollie",
- "MultiSafepay",
- "Netaxept",
- "NetBanx",
- "PayFast",
- "Payflow_Pro",
- "PaymentExpress_PxPay",
- "PaymentExpress_PxPost",
- "PayPal_Express",
- "PayPal_Pro",
- "Pin",
- "SagePay_Direct",
- "SagePay_Server",
- "SecurePay_DirectPost",
- "Stripe",
- "TargetPay_Directebanking",
- "TargetPay_Ideal",
- "TargetPay_Mrcash",
- "WorldPay"
- ]
+ "dev-master": "3.1.x-dev"
+ }
+ },
+ "suggest": {
+ "league/omnipay": "The default Omnipay package provides a default HTTP Adapter."
+ },
+ "scripts": {
+ "test": "phpunit",
+ "check-style": "phpcs -p --standard=PSR2 src/",
+ "fix-style": "phpcbf -p --standard=PSR2 src/"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "config": {
+ "allow-plugins": {
+ "php-http/discovery": true
+ }
}
}
diff --git a/makedoc.sh b/makedoc.sh
deleted file mode 100755
index 0d258cae..00000000
--- a/makedoc.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-mkdir -p ./reports
-mkdir -p ./documents/apigen
-
-if [ -z "$1" ]; then
- apigen generate \
- --title 'Onmipay Common API documentation' \
- --source ./src \
- --destination ./documents/apigen
-
-#
-# Left here for further expansion, ignore this for the time being.
-#
-elif [ "$1" = "common" ]; then
- apigen generate \
- --title 'Omnipay Common API documentation' \
- --source ./src/Omnipay/Common \
- --destination ./documents/apigen
-fi
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index a61160cd..21263b81 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 00000000..ab4e9d38
--- /dev/null
+++ b/phpunit9.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+ src/
+
+
+
+
+
+
+
+
+
+ tests
+
+
+
+
+
+
diff --git a/src/Omnipay/Common/AbstractGateway.php b/src/Common/AbstractGateway.php
similarity index 89%
rename from src/Omnipay/Common/AbstractGateway.php
rename to src/Common/AbstractGateway.php
index 97014a0f..33443360 100755
--- a/src/Omnipay/Common/AbstractGateway.php
+++ b/src/Common/AbstractGateway.php
@@ -5,8 +5,8 @@
namespace Omnipay\Common;
-use Guzzle\Http\ClientInterface;
-use Guzzle\Http\Client as HttpClient;
+use Omnipay\Common\Http\Client;
+use Omnipay\Common\Http\ClientInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
@@ -15,7 +15,7 @@
*
* This abstract class should be extended by all payment gateways
* throughout the Omnipay system. It enforces implementation of
- * the GatewayInterface interface and defines various common attibutes
+ * the GatewayInterface interface and defines various common attributes
* and methods that all gateways should have.
*
* Example:
@@ -40,17 +40,16 @@
*
* For further code examples see the *omnipay-example* repository on github.
*
- * @see GatewayInterface
*/
abstract class AbstractGateway implements GatewayInterface
{
- /**
- * @var \Symfony\Component\HttpFoundation\ParameterBag
- */
- protected $parameters;
+ use ParametersTrait {
+ setParameter as traitSetParameter;
+ getParameter as traitGetParameter;
+ }
/**
- * @var \Guzzle\Http\ClientInterface
+ * @var ClientInterface
*/
protected $httpClient;
@@ -62,10 +61,10 @@ abstract class AbstractGateway implements GatewayInterface
/**
* Create a new gateway instance
*
- * @param ClientInterface $httpClient A Guzzle client to make API calls with
+ * @param ClientInterface $httpClient A HTTP client to make API calls with
* @param HttpRequest $httpRequest A Symfony HTTP request object
*/
- public function __construct(ClientInterface $httpClient = null, HttpRequest $httpRequest = null)
+ public function __construct(?ClientInterface $httpClient = null, ?HttpRequest $httpRequest = null)
{
$this->httpClient = $httpClient ?: $this->getDefaultHttpClient();
$this->httpRequest = $httpRequest ?: $this->getDefaultHttpRequest();
@@ -114,21 +113,13 @@ public function getDefaultParameters()
return array();
}
- /**
- * @return array
- */
- public function getParameters()
- {
- return $this->parameters->all();
- }
-
/**
* @param string $key
* @return mixed
*/
public function getParameter($key)
{
- return $this->parameters->get($key);
+ return $this->traitGetParameter($key);
}
/**
@@ -138,9 +129,7 @@ public function getParameter($key)
*/
public function setParameter($key, $value)
{
- $this->parameters->set($key, $value);
-
- return $this;
+ return $this->traitSetParameter($key, $value);
}
/**
@@ -227,6 +216,16 @@ public function supportsCompletePurchase()
return method_exists($this, 'completePurchase');
}
+ /**
+ * Supports Fetch Transaction
+ *
+ * @return boolean True if this gateway supports the fetchTransaction() method
+ */
+ public function supportsFetchTransaction()
+ {
+ return method_exists($this, 'fetchTransaction');
+ }
+
/**
* Supports Refund
*
@@ -312,7 +311,6 @@ public function supportsUpdateCard()
* $myRequest = $gw->myRequest($someParameters);
*
*
- * @see \Omnipay\Common\Message\AbstractRequest
* @param string $class The request class name
* @param array $parameters
* @return \Omnipay\Common\Message\AbstractRequest
@@ -327,16 +325,11 @@ protected function createRequest($class, array $parameters)
/**
* Get the global default HTTP client.
*
- * @return HttpClient
+ * @return ClientInterface
*/
protected function getDefaultHttpClient()
{
- return new HttpClient(
- '',
- array(
- 'curl.options' => array(CURLOPT_CONNECTTIMEOUT => 60),
- )
- );
+ return new Client();
}
/**
diff --git a/src/Omnipay/Common/CreditCard.php b/src/Common/CreditCard.php
similarity index 86%
rename from src/Omnipay/Common/CreditCard.php
rename to src/Common/CreditCard.php
index f08f342d..a1f97d05 100644
--- a/src/Omnipay/Common/CreditCard.php
+++ b/src/Common/CreditCard.php
@@ -93,6 +93,8 @@
*/
class CreditCard
{
+ use ParametersTrait;
+
const BRAND_VISA = 'visa';
const BRAND_MASTERCARD = 'mastercard';
const BRAND_DISCOVER = 'discover';
@@ -133,13 +135,6 @@ class CreditCard
self::BRAND_LASER => '/^(6304|6706|6709|6771(?!89))\d{8}(\d{4}|\d{6,7})?$/',
);
- /**
- * Internal storage of all of the card parameters.
- *
- * @var \Symfony\Component\HttpFoundation\ParameterBag
- */
- protected $parameters;
-
/**
* Create a new CreditCard object using the specified parameters
*
@@ -156,7 +151,6 @@ public function __construct($parameters = null)
* Note: The fact that this class knows about a particular card brand does not imply
* that your gateway supports it.
*
- * @see self::$supported_cards
* @return array
*/
public function getSupportedBrands()
@@ -194,9 +188,9 @@ public function addSupportedBrand($name, $expression)
* If any unknown parameters passed, they will be ignored.
*
* @param array $parameters An associative array of parameters
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
- public function initialize($parameters = null)
+ public function initialize(?array $parameters = null)
{
$this->parameters = new ParameterBag;
@@ -205,40 +199,6 @@ public function initialize($parameters = null)
return $this;
}
- /**
- * Get all parameters.
- *
- * @return array An associative array of parameters.
- */
- public function getParameters()
- {
- return $this->parameters->all();
- }
-
- /**
- * Get one parameter.
- *
- * @return mixed A single parameter value.
- */
- protected function getParameter($key)
- {
- return $this->parameters->get($key);
- }
-
- /**
- * Set one parameter.
- *
- * @param string $key Parameter key
- * @param mixed $value Parameter value
- * @return CreditCard provides a fluent interface.
- */
- protected function setParameter($key, $value)
- {
- $this->parameters->set($key, $value);
-
- return $this;
- }
-
/**
* Set the credit card year.
*
@@ -246,7 +206,7 @@ protected function setParameter($key, $value)
*
* @param string $key Parameter key, e.g. 'expiryYear'
* @param mixed $value Parameter value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
protected function setYearParameter($key, $value)
{
@@ -269,14 +229,21 @@ protected function setYearParameter($key, $value)
* Generally if you want to validate the credit card yourself with custom error
* messages, you should use your framework's validation library, not this method.
*
- * @throws InvalidCreditCardException
* @return void
+ * @throws Exception\InvalidRequestException
+ * @throws InvalidCreditCardException
*/
public function validate()
{
- foreach (array('number', 'expiryMonth', 'expiryYear') as $key) {
+ $requiredParameters = array(
+ 'number' => 'credit card number',
+ 'expiryMonth' => 'expiration month',
+ 'expiryYear' => 'expiration year'
+ );
+
+ foreach ($requiredParameters as $key => $val) {
if (!$this->getParameter($key)) {
- throw new InvalidCreditCardException("The $key parameter is required");
+ throw new InvalidCreditCardException("The $val is required");
}
}
@@ -292,7 +259,6 @@ public function validate()
throw new InvalidCreditCardException('Card number should have 12 to 19 digits');
}
}
-
/**
* Get Card Title.
*
@@ -307,7 +273,7 @@ public function getTitle()
* Set Card Title.
*
* @param string $value Parameter value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setTitle($value)
{
@@ -331,7 +297,7 @@ public function getFirstName()
* Set Card First Name (Billing and Shipping).
*
* @param string $value Parameter value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setFirstName($value)
{
@@ -355,7 +321,7 @@ public function getLastName()
* Set Card Last Name (Billing and Shipping).
*
* @param string $value Parameter value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setLastName($value)
{
@@ -379,7 +345,7 @@ public function getName()
* Set Card Name (Billing and Shipping).
*
* @param string $value Parameter value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setName($value)
{
@@ -406,12 +372,12 @@ public function getNumber()
* it's safe to pass in strings such as "4444-3333 2222 1111" etc.
*
* @param string $value Parameter value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setNumber($value)
{
// strip non-numeric characters
- return $this->setParameter('number', preg_replace('/\D/', '', $value));
+ return $this->setParameter('number', preg_replace('/\D/', '', (string) $value));
}
/**
@@ -446,8 +412,10 @@ public function getNumberMasked($mask = 'X')
*/
public function getBrand()
{
+ $number = (string) $this->getNumber();
+
foreach ($this->getSupportedBrands() as $brand => $val) {
- if (preg_match($val, $this->getNumber())) {
+ if (preg_match($val, $number)) {
return $brand;
}
}
@@ -467,7 +435,7 @@ public function getExpiryMonth()
* Sets the card expiry month.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setExpiryMonth($value)
{
@@ -488,7 +456,7 @@ public function getExpiryYear()
* Sets the card expiry year.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setExpiryYear($value)
{
@@ -521,7 +489,7 @@ public function getStartMonth()
* Sets the card start month.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setStartMonth($value)
{
@@ -542,7 +510,7 @@ public function getStartYear()
* Sets the card start year.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setStartYear($value)
{
@@ -575,7 +543,7 @@ public function getCvv()
* Sets the card CVV.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setCvv($value)
{
@@ -595,35 +563,36 @@ public function getTracks()
/**
* Get raw data for track 1 on the credit card magnetic strip.
*
- * @return string
+ * @return string|null
*/
public function getTrack1()
{
- $track1 = null;
- if ($tracks = $this->getTracks()) {
- $pattern = '/\%B\d{1,19}\^.{2,26}\^\d{4}\d*\?/';
- if (preg_match($pattern, $tracks, $matches) === 1) {
- $track1 = $matches[0];
- }
- }
- return $track1;
+ return $this->getTrackByPattern('/\%B\d{1,19}\^.{2,26}\^\d{4}\d*\?/');
}
/**
* Get raw data for track 2 on the credit card magnetic strip.
*
- * @return string
+ * @return string|null
*/
public function getTrack2()
{
- $track2 = null;
+ return $this->getTrackByPattern('/;\d{1,19}=\d{4}\d*\?/');
+ }
+
+ /**
+ * Get raw data for a track on the credit card magnetic strip based on the pattern for track 1 or 2.
+ *
+ * @param $pattern
+ * @return string|null
+ */
+ protected function getTrackByPattern($pattern)
+ {
if ($tracks = $this->getTracks()) {
- $pattern = '/;\d{1,19}=\d{4}\d*\?/';
if (preg_match($pattern, $tracks, $matches) === 1) {
- $track2 = $matches[0];
+ return $matches[0];
}
}
- return $track2;
}
/**
@@ -631,7 +600,7 @@ public function getTrack2()
* transactions.
*
* @param $value
- * @return CreditCard
+ * @return $this
*/
public function setTracks($value)
{
@@ -652,7 +621,7 @@ public function getIssueNumber()
* Sets the card issue number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setIssueNumber($value)
{
@@ -673,7 +642,7 @@ public function getBillingTitle()
* Sets the card billing title.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingTitle($value)
{
@@ -690,17 +659,31 @@ public function getBillingName()
return trim($this->getBillingFirstName() . ' ' . $this->getBillingLastName());
}
+ /**
+ * Split the full name in the first and last name.
+ *
+ * @param $fullName
+ * @return array with first and lastname
+ */
+ protected function listFirstLastName($fullName)
+ {
+ $names = explode(' ', $fullName, 2);
+
+ return [$names[0], isset($names[1]) ? $names[1] : null];
+ }
+
/**
* Sets the card billing name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingName($value)
{
- $names = explode(' ', $value, 2);
+ $names = $this->listFirstLastName($value);
+
$this->setBillingFirstName($names[0]);
- $this->setBillingLastName(isset($names[1]) ? $names[1] : null);
+ $this->setBillingLastName($names[1]);
return $this;
}
@@ -719,7 +702,7 @@ public function getBillingFirstName()
* Sets the first part of the card billing name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingFirstName($value)
{
@@ -740,7 +723,7 @@ public function getBillingLastName()
* Sets the last part of the card billing name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingLastName($value)
{
@@ -761,7 +744,7 @@ public function getBillingCompany()
* Sets the billing company name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingCompany($value)
{
@@ -782,7 +765,7 @@ public function getBillingAddress1()
* Sets the billing address, line 1.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingAddress1($value)
{
@@ -803,7 +786,7 @@ public function getBillingAddress2()
* Sets the billing address, line 2.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingAddress2($value)
{
@@ -824,7 +807,7 @@ public function getBillingCity()
* Sets billing city.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingCity($value)
{
@@ -845,7 +828,7 @@ public function getBillingPostcode()
* Sets the billing postcode.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingPostcode($value)
{
@@ -866,7 +849,7 @@ public function getBillingState()
* Sets the billing state.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingState($value)
{
@@ -887,7 +870,7 @@ public function getBillingCountry()
* Sets the billing country name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingCountry($value)
{
@@ -908,7 +891,7 @@ public function getBillingPhone()
* Sets the billing phone number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingPhone($value)
{
@@ -929,7 +912,7 @@ public function getBillingPhoneExtension()
* Sets the billing phone number extension.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingPhoneExtension($value)
{
@@ -950,7 +933,7 @@ public function getBillingFax()
* Sets the billing fax number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBillingFax($value)
{
@@ -971,7 +954,7 @@ public function getShippingTitle()
* Sets the title of the card shipping name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingTitle($value)
{
@@ -992,13 +975,14 @@ public function getShippingName()
* Sets the card shipping name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingName($value)
{
- $names = explode(' ', $value, 2);
+ $names = $this->listFirstLastName($value);
+
$this->setShippingFirstName($names[0]);
- $this->setShippingLastName(isset($names[1]) ? $names[1] : null);
+ $this->setShippingLastName($names[1]);
return $this;
}
@@ -1017,7 +1001,7 @@ public function getShippingFirstName()
* Sets the first part of the card shipping name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingFirstName($value)
{
@@ -1038,7 +1022,7 @@ public function getShippingLastName()
* Sets the last part of the card shipping name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingLastName($value)
{
@@ -1059,7 +1043,7 @@ public function getShippingCompany()
* Sets the shipping company name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingCompany($value)
{
@@ -1080,7 +1064,7 @@ public function getShippingAddress1()
* Sets the shipping address, line 1.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingAddress1($value)
{
@@ -1101,7 +1085,7 @@ public function getShippingAddress2()
* Sets the shipping address, line 2.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingAddress2($value)
{
@@ -1122,7 +1106,7 @@ public function getShippingCity()
* Sets the shipping city.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingCity($value)
{
@@ -1143,7 +1127,7 @@ public function getShippingPostcode()
* Sets the shipping postcode.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingPostcode($value)
{
@@ -1164,7 +1148,7 @@ public function getShippingState()
* Sets the shipping state.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingState($value)
{
@@ -1185,7 +1169,7 @@ public function getShippingCountry()
* Sets the shipping country.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingCountry($value)
{
@@ -1206,7 +1190,7 @@ public function getShippingPhone()
* Sets the shipping phone number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingPhone($value)
{
@@ -1227,7 +1211,7 @@ public function getShippingPhoneExtension()
* Sets the shipping phone number extension.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingPhoneExtension($value)
{
@@ -1248,7 +1232,7 @@ public function getShippingFax()
* Sets the shipping fax number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setShippingFax($value)
{
@@ -1269,7 +1253,7 @@ public function getAddress1()
* Sets the billing and shipping address, line 1.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setAddress1($value)
{
@@ -1293,7 +1277,7 @@ public function getAddress2()
* Sets the billing and shipping address, line 2.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setAddress2($value)
{
@@ -1317,7 +1301,7 @@ public function getCity()
* Sets the billing and shipping city.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setCity($value)
{
@@ -1341,7 +1325,7 @@ public function getPostcode()
* Sets the billing and shipping postcode.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setPostcode($value)
{
@@ -1365,7 +1349,7 @@ public function getState()
* Sets the billing and shipping state.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setState($value)
{
@@ -1389,7 +1373,7 @@ public function getCountry()
* Sets the billing and shipping country.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setCountry($value)
{
@@ -1413,7 +1397,7 @@ public function getPhone()
* Sets the billing and shipping phone number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setPhone($value)
{
@@ -1437,7 +1421,7 @@ public function getPhoneExtension()
* Sets the billing and shipping phone number extension.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setPhoneExtension($value)
{
@@ -1461,7 +1445,7 @@ public function getFax()
* Sets the billing and shipping fax number.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setFax($value)
{
@@ -1485,7 +1469,7 @@ public function getCompany()
* Sets the billing and shipping company name.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setCompany($value)
{
@@ -1509,7 +1493,7 @@ public function getEmail()
* Sets the cardholder's email address.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setEmail($value)
{
@@ -1532,7 +1516,7 @@ public function getBirthday($format = 'Y-m-d')
* Sets the cardholder's birthday.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setBirthday($value)
{
@@ -1559,7 +1543,7 @@ public function getGender()
* Sets the cardholder's gender.
*
* @param string $value
- * @return CreditCard provides a fluent interface.
+ * @return $this
*/
public function setGender($value)
{
diff --git a/src/Omnipay/Common/Exception/BadMethodCallException.php b/src/Common/Exception/BadMethodCallException.php
similarity index 100%
rename from src/Omnipay/Common/Exception/BadMethodCallException.php
rename to src/Common/Exception/BadMethodCallException.php
diff --git a/src/Omnipay/Common/Exception/InvalidCreditCardException.php b/src/Common/Exception/InvalidCreditCardException.php
similarity index 100%
rename from src/Omnipay/Common/Exception/InvalidCreditCardException.php
rename to src/Common/Exception/InvalidCreditCardException.php
diff --git a/src/Omnipay/Common/Exception/InvalidRequestException.php b/src/Common/Exception/InvalidRequestException.php
similarity index 100%
rename from src/Omnipay/Common/Exception/InvalidRequestException.php
rename to src/Common/Exception/InvalidRequestException.php
diff --git a/src/Omnipay/Common/Exception/InvalidResponseException.php b/src/Common/Exception/InvalidResponseException.php
similarity index 100%
rename from src/Omnipay/Common/Exception/InvalidResponseException.php
rename to src/Common/Exception/InvalidResponseException.php
diff --git a/src/Omnipay/Common/Exception/OmnipayException.php b/src/Common/Exception/OmnipayException.php
similarity index 100%
rename from src/Omnipay/Common/Exception/OmnipayException.php
rename to src/Common/Exception/OmnipayException.php
diff --git a/src/Omnipay/Common/Exception/RuntimeException.php b/src/Common/Exception/RuntimeException.php
similarity index 100%
rename from src/Omnipay/Common/Exception/RuntimeException.php
rename to src/Common/Exception/RuntimeException.php
diff --git a/src/Omnipay/Common/GatewayFactory.php b/src/Common/GatewayFactory.php
similarity index 66%
rename from src/Omnipay/Common/GatewayFactory.php
rename to src/Common/GatewayFactory.php
index f81ba667..8d887d59 100644
--- a/src/Omnipay/Common/GatewayFactory.php
+++ b/src/Common/GatewayFactory.php
@@ -5,8 +5,8 @@
namespace Omnipay\Common;
-use Guzzle\Http\ClientInterface;
use Omnipay\Common\Exception\RuntimeException;
+use Omnipay\Common\Http\ClientInterface;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
/**
@@ -26,7 +26,6 @@
* $gateway = Omnipay::create('ExpressGateway');
*
*
- * @see Omnipay\Omnipay
*/
class GatewayFactory
{
@@ -69,35 +68,16 @@ public function register($className)
}
}
- /**
- * Automatically find and register all officially supported gateways
- *
- * @return array An array of gateway names
- */
- public function find()
- {
- foreach ($this->getSupportedGateways() as $gateway) {
- $class = Helper::getGatewayClassName($gateway);
- if (class_exists($class)) {
- $this->register($gateway);
- }
- }
-
- ksort($this->gateways);
-
- return $this->all();
- }
-
/**
* Create a new gateway instance
*
* @param string $class Gateway name
- * @param ClientInterface|null $httpClient A Guzzle HTTP Client implementation
+ * @param ClientInterface|null $httpClient A HTTP Client implementation
* @param HttpRequest|null $httpRequest A Symfony HTTP Request implementation
* @throws RuntimeException If no such gateway is found
* @return GatewayInterface An object of class $class is created and returned
*/
- public function create($class, ClientInterface $httpClient = null, HttpRequest $httpRequest = null)
+ public function create($class, ?ClientInterface $httpClient = null, ?HttpRequest $httpRequest = null)
{
$class = Helper::getGatewayClassName($class);
@@ -107,16 +87,4 @@ public function create($class, ClientInterface $httpClient = null, HttpRequest $
return new $class($httpClient, $httpRequest);
}
-
- /**
- * Get a list of supported gateways which may be available
- *
- * @return array
- */
- public function getSupportedGateways()
- {
- $package = json_decode(file_get_contents(__DIR__.'/../../../composer.json'), true);
-
- return $package['extra']['gateways'];
- }
}
diff --git a/src/Omnipay/Common/GatewayInterface.php b/src/Common/GatewayInterface.php
similarity index 71%
rename from src/Omnipay/Common/GatewayInterface.php
rename to src/Common/GatewayInterface.php
index 86d57717..34218c96 100644
--- a/src/Omnipay/Common/GatewayInterface.php
+++ b/src/Common/GatewayInterface.php
@@ -11,35 +11,39 @@
* This interface class defines the standard functions that any
* Omnipay gateway needs to define.
*
- * @see AbstractGateway
*
- * @method \Omnipay\Common\Message\RequestInterface authorize(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\NotificationInterface acceptNotification(array $options = array()) (Optional method)
+ * Receive and handle an instant payment notification (IPN)
+ * @method \Omnipay\Common\Message\RequestInterface authorize(array $options = array()) (Optional method)
* Authorize an amount on the customers card
- * @method \Omnipay\Common\Message\RequestInterface completeAuthorize(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface completeAuthorize(array $options = array()) (Optional method)
* Handle return from off-site gateways after authorization
- * @method \Omnipay\Common\Message\RequestInterface capture(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface capture(array $options = array()) (Optional method)
* Capture an amount you have previously authorized
- * @method \Omnipay\Common\Message\RequestInterface purchase(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface purchase(array $options = array()) (Optional method)
* Authorize and immediately capture an amount on the customers card
- * @method \Omnipay\Common\Message\RequestInterface completePurchase(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface completePurchase(array $options = array()) (Optional method)
* Handle return from off-site gateways after purchase
- * @method \Omnipay\Common\Message\RequestInterface refund(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface refund(array $options = array()) (Optional method)
* Refund an already processed transaction
- * @method \Omnipay\Common\Message\RequestInterface void(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface fetchTransaction(array $options = []) (Optional method)
+ * Fetches transaction information
+ * @method \Omnipay\Common\Message\RequestInterface void(array $options = array()) (Optional method)
* Generally can only be called up to 24 hours after submitting a transaction
- * @method \Omnipay\Common\Message\RequestInterface createCard(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface createCard(array $options = array()) (Optional method)
* The returned response object includes a cardReference, which can be used for future transactions
- * @method \Omnipay\Common\Message\RequestInterface updateCard(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface updateCard(array $options = array()) (Optional method)
* Update a stored card
- * @method \Omnipay\Common\Message\RequestInterface deleteCard(array $options = array()) (Optional method)
+ * @method \Omnipay\Common\Message\RequestInterface deleteCard(array $options = array()) (Optional method)
* Delete a stored card
-*/
+ */
interface GatewayInterface
{
/**
* Get gateway display name
*
* This can be used by carts to get the display name for each gateway.
+ * @return string
*/
public function getName();
@@ -48,6 +52,7 @@ public function getName();
*
* This name can be used with GatewayFactory as an alias of the gateway class,
* to create new instances of this gateway.
+ * @return string
*/
public function getShortName();
@@ -59,17 +64,18 @@ public function getShortName();
* 'testMode' => false, // boolean variable
* 'landingPage' => array('billing', 'login'), // enum variable, first item is default
* );
+ * @return array
*/
public function getDefaultParameters();
/**
* Initialize gateway with parameters
+ * @return $this
*/
public function initialize(array $parameters = array());
/**
* Get all gateway parameters
- *
* @return array
*/
public function getParameters();
diff --git a/src/Omnipay/Common/Helper.php b/src/Common/Helper.php
similarity index 76%
rename from src/Omnipay/Common/Helper.php
rename to src/Common/Helper.php
index 13637378..7886aecd 100644
--- a/src/Omnipay/Common/Helper.php
+++ b/src/Common/Helper.php
@@ -42,6 +42,7 @@ function ($match) {
protected static function convertToLowercase($str)
{
$explodedStr = explode('_', $str);
+ $lowercasedStr = [];
if (count($explodedStr) > 1) {
foreach ($explodedStr as $value) {
@@ -62,7 +63,7 @@ protected static function convertToLowercase($str)
public static function validateLuhn($number)
{
$str = '';
- foreach (array_reverse(str_split($number)) as $i => $c) {
+ foreach (array_reverse(str_split((string) $number)) as $i => $c) {
$str .= $i % 2 ? $c * 2 : $c;
}
@@ -78,9 +79,9 @@ public static function validateLuhn($number)
* @param mixed $target The object to set parameters on
* @param array $parameters An array of parameters to set
*/
- public static function initialize($target, $parameters)
+ public static function initialize($target, ?array $parameters = null)
{
- if (is_array($parameters)) {
+ if ($parameters) {
foreach ($parameters as $key => $value) {
$method = 'set'.ucfirst(static::camelCase($key));
if (method_exists($target, $method)) {
@@ -121,12 +122,18 @@ public static function getGatewayShortName($className)
* PayPal\Express => \Omnipay\PayPal\ExpressGateway
* PayPal_Express => \Omnipay\PayPal\ExpressGateway
*
- * @param string $shortName The short gateway name
+ * @param string $shortName The short gateway name or the FQCN
* @return string The fully namespaced gateway class name
*/
public static function getGatewayClassName($shortName)
{
- if (0 === strpos($shortName, '\\')) {
+ // If the class starts with \ or Omnipay\, assume it's a FQCN
+ if (0 === strpos($shortName, '\\') || 0 === strpos($shortName, 'Omnipay\\')) {
+ return $shortName;
+ }
+
+ // Check if the class exists and implements the Gateway Interface, if so -> FCQN
+ if (is_subclass_of($shortName, GatewayInterface::class, true)) {
return $shortName;
}
@@ -138,30 +145,4 @@ public static function getGatewayClassName($shortName)
return '\\Omnipay\\'.$shortName.'Gateway';
}
-
- /**
- * Convert an amount into a float.
- * The float datatype can then be converted into the string
- * format that the remote gateway requies.
- *
- * @var string|int|float $value The value to convert.
- * @throws InvalidArgumentException on a validation failure.
- * @return float The amount converted to a float.
- */
-
- public static function toFloat($value)
- {
- if (!is_string($value) && !is_int($value) && !is_float($value)) {
- throw new InvalidArgumentException('Data type is not a valid decimal number.');
- }
-
- if (is_string($value)) {
- // Validate generic number, with optional sign and decimals.
- if (!preg_match('/^[-]?[0-9]+(\.[0-9]*)?$/', $value)) {
- throw new InvalidArgumentException('String is not a valid decimal number.');
- }
- }
-
- return (float)$value;
- }
}
diff --git a/src/Common/Http/Client.php b/src/Common/Http/Client.php
new file mode 100644
index 00000000..7eece585
--- /dev/null
+++ b/src/Common/Http/Client.php
@@ -0,0 +1,72 @@
+httpClient = $httpClient ?: HttpClientDiscovery::find();
+ $this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find();
+ }
+
+ /**
+ * @param $method
+ * @param $uri
+ * @param array $headers
+ * @param string|array|resource|StreamInterface|null $body
+ * @param string $protocolVersion
+ * @return ResponseInterface
+ * @throws \Http\Client\Exception
+ */
+ public function request(
+ $method,
+ $uri,
+ array $headers = [],
+ $body = null,
+ $protocolVersion = '1.1'
+ ) {
+ $request = $this->requestFactory->createRequest($method, $uri, $headers, $body, $protocolVersion);
+
+ return $this->sendRequest($request);
+ }
+
+ /**
+ * @param RequestInterface $request
+ * @return ResponseInterface
+ * @throws \Http\Client\Exception
+ */
+ private function sendRequest(RequestInterface $request)
+ {
+ try {
+ return $this->httpClient->sendRequest($request);
+ } catch (\Http\Client\Exception\NetworkException $networkException) {
+ throw new NetworkException($networkException->getMessage(), $request, $networkException);
+ } catch (\Exception $exception) {
+ throw new RequestException($exception->getMessage(), $request, $exception);
+ }
+ }
+}
diff --git a/src/Common/Http/ClientInterface.php b/src/Common/Http/ClientInterface.php
new file mode 100644
index 00000000..73593957
--- /dev/null
+++ b/src/Common/Http/ClientInterface.php
@@ -0,0 +1,34 @@
+request = $request;
+
+ parent::__construct($message, 0, $previous);
+ }
+
+ /**
+ * Returns the request.
+ *
+ * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
+ *
+ * @return RequestInterface
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+}
diff --git a/src/Common/Http/Exception/NetworkException.php b/src/Common/Http/Exception/NetworkException.php
new file mode 100644
index 00000000..068133dc
--- /dev/null
+++ b/src/Common/Http/Exception/NetworkException.php
@@ -0,0 +1,9 @@
+initialize($parameters);
}
@@ -37,7 +33,7 @@ public function __construct($parameters = null)
* @param array|null $parameters An array of parameters to set on this object
* @return $this Item
*/
- public function initialize($parameters = null)
+ public function initialize(?array $parameters = null)
{
$this->parameters = new ParameterBag;
@@ -46,23 +42,6 @@ public function initialize($parameters = null)
return $this;
}
- public function getParameters()
- {
- return $this->parameters->all();
- }
-
- protected function getParameter($key)
- {
- return $this->parameters->get($key);
- }
-
- protected function setParameter($key, $value)
- {
- $this->parameters->set($key, $value);
-
- return $this;
- }
-
/**
* {@inheritDoc}
*/
diff --git a/src/Omnipay/Common/ItemBag.php b/src/Common/ItemBag.php
similarity index 92%
rename from src/Omnipay/Common/ItemBag.php
rename to src/Common/ItemBag.php
index f726c3b7..7515335b 100644
--- a/src/Omnipay/Common/ItemBag.php
+++ b/src/Common/ItemBag.php
@@ -11,14 +11,12 @@
* This class defines a bag (multi element set or array) of single cart items
* in the Omnipay system.
*
- * @see Item
*/
class ItemBag implements \IteratorAggregate, \Countable
{
/**
* Item storage
*
- * @see Item
*
* @var array
*/
@@ -37,7 +35,6 @@ public function __construct(array $items = array())
/**
* Return all the items
*
- * @see Item
*
* @return array An array of items
*/
@@ -49,7 +46,6 @@ public function all()
/**
* Replace the contents of this bag with the specified items
*
- * @see Item
*
* @param array $items An array of items
*/
@@ -65,7 +61,6 @@ public function replace(array $items = array())
/**
* Add an item to the bag
*
- * @see Item
*
* @param ItemInterface|array $item An existing item, or associative array of item parameters
*/
@@ -83,7 +78,7 @@ public function add($item)
*
* @return \ArrayIterator An \ArrayIterator instance
*/
- public function getIterator()
+ public function getIterator(): \Traversable
{
return new \ArrayIterator($this->items);
}
@@ -93,7 +88,7 @@ public function getIterator()
*
* @return int The number of items
*/
- public function count()
+ public function count(): int
{
return count($this->items);
}
diff --git a/src/Omnipay/Common/ItemInterface.php b/src/Common/ItemInterface.php
similarity index 100%
rename from src/Omnipay/Common/ItemInterface.php
rename to src/Common/ItemInterface.php
diff --git a/src/Omnipay/Common/Message/AbstractRequest.php b/src/Common/Message/AbstractRequest.php
similarity index 72%
rename from src/Omnipay/Common/Message/AbstractRequest.php
rename to src/Common/Message/AbstractRequest.php
index 14d34ce1..004a7757 100644
--- a/src/Omnipay/Common/Message/AbstractRequest.php
+++ b/src/Common/Message/AbstractRequest.php
@@ -5,16 +5,22 @@
namespace Omnipay\Common\Message;
-use Guzzle\Http\ClientInterface;
+use Money\Currencies\ISOCurrencies;
+use Money\Currency;
+use Money\Formatter\DecimalMoneyFormatter;
+use Money\Money;
+use Money\Number;
+use Money\Parser\DecimalMoneyParser;
use Omnipay\Common\CreditCard;
-use Omnipay\Common\Currency;
use Omnipay\Common\Exception\InvalidRequestException;
use Omnipay\Common\Exception\RuntimeException;
use Omnipay\Common\Helper;
+use Omnipay\Common\Http\Client;
+use Omnipay\Common\Http\ClientInterface;
use Omnipay\Common\ItemBag;
+use Omnipay\Common\ParametersTrait;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
-use InvalidArgumentException;
/**
* Abstract Request
@@ -56,22 +62,17 @@
* // now do something with the $myResponse object, test for success, etc.
*
*
- * @see RequestInterface
- * @see AbstractResponse
*/
abstract class AbstractRequest implements RequestInterface
{
- /**
- * The request parameters
- *
- * @var \Symfony\Component\HttpFoundation\ParameterBag
- */
- protected $parameters;
+ use ParametersTrait {
+ setParameter as traitSetParameter;
+ }
/**
* The request client.
*
- * @var \Guzzle\Http\ClientInterface
+ * @var ClientInterface
*/
protected $httpClient;
@@ -89,6 +90,11 @@ abstract class AbstractRequest implements RequestInterface
*/
protected $response;
+ /**
+ * @var ISOCurrencies
+ */
+ protected $currencies;
+
/**
* @var bool
*/
@@ -102,7 +108,7 @@ abstract class AbstractRequest implements RequestInterface
/**
* Create a new Request
*
- * @param ClientInterface $httpClient A Guzzle client to make API calls with
+ * @param ClientInterface $httpClient A HTTP client to make API calls with
* @param HttpRequest $httpRequest A Symfony HTTP request object
*/
public function __construct(ClientInterface $httpClient, HttpRequest $httpRequest)
@@ -135,33 +141,12 @@ public function initialize(array $parameters = array())
return $this;
}
- /**
- * Get all parameters as an associative array.
- *
- * @return array
- */
- public function getParameters()
- {
- return $this->parameters->all();
- }
-
- /**
- * Get a single parameter.
- *
- * @param string $key The parameter key
- * @return mixed
- */
- protected function getParameter($key)
- {
- return $this->parameters->get($key);
- }
-
/**
* Set a single parameter
*
* @param string $key The parameter key
* @param mixed $value The value to set
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
* @throws RuntimeException if a request parameter is modified after the request has been sent.
*/
protected function setParameter($key, $value)
@@ -170,9 +155,7 @@ protected function setParameter($key, $value)
throw new RuntimeException('Request cannot be modified after it has been sent!');
}
- $this->parameters->set($key, $value);
-
- return $this;
+ return $this->traitSetParameter($key, $value);
}
/**
@@ -189,32 +172,13 @@ public function getTestMode()
* Sets the test mode of the request.
*
* @param boolean $value True for test mode on.
- * @return AbstractRequest
+ * @return $this
*/
public function setTestMode($value)
{
return $this->setParameter('testMode', $value);
}
- /**
- * Validate the request.
- *
- * This method is called internally by gateways to avoid wasting time with an API call
- * when the request is clearly invalid.
- *
- * @param string ... a variable length list of required parameters
- * @throws InvalidRequestException
- */
- public function validate()
- {
- foreach (func_get_args() as $key) {
- $value = $this->parameters->get($key);
- if (! isset($value)) {
- throw new InvalidRequestException("The $key parameter is required");
- }
- }
- }
-
/**
* Get the card.
*
@@ -229,7 +193,7 @@ public function getCard()
* Sets the card.
*
* @param CreditCard $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setCard($value)
{
@@ -254,7 +218,7 @@ public function getToken()
* Sets the card token.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setToken($value)
{
@@ -275,7 +239,7 @@ public function getCardReference()
* Sets the card reference.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setCardReference($value)
{
@@ -283,76 +247,89 @@ public function setCardReference($value)
}
/**
- * Convert an amount into a float.
- *
- * @var string|int|float $value The value to convert.
- * @throws InvalidRequestException on any validation failure.
- * @return float The amount converted to a float.
+ * @return ISOCurrencies
*/
-
- public function toFloat($value)
+ protected function getCurrencies()
{
- try {
- return Helper::toFloat($value);
- } catch (InvalidArgumentException $e) {
- // Throw old exception for legacy implementations.
- throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e);
+ if ($this->currencies === null) {
+ $this->currencies = new ISOCurrencies();
}
+
+ return $this->currencies;
}
/**
- * Validates and returns the formated amount.
- *
- * @throws InvalidRequestException on any validation failure.
- * @return string The amount formatted to the correct number of decimal places for the selected currency.
+ * @param string|int|null $amount
+ * @return null|Money
+ * @throws InvalidRequestException
*/
- public function getAmount()
+ private function getMoney($amount = null)
{
- $amount = $this->getParameter('amount');
-
- if ($amount !== null) {
- // Don't allow integers for currencies that support decimals.
- // This is for legacy reasons - upgrades from v0.9
- if ($this->getCurrencyDecimalPlaces() > 0) {
- if (is_int($amount) || (is_string($amount) && false === strpos((string) $amount, '.'))) {
- throw new InvalidRequestException(
- 'Please specify amount as a string or float, '
- . 'with decimal places (e.g. \'10.00\' to represent $10.00).'
- );
- };
- }
+ $currencyCode = $this->getCurrency() ?: 'USD';
+ $currency = new Currency($currencyCode);
- $amount = $this->toFloat($amount);
+ $amount = $amount !== null ? $amount : $this->getParameter('amount');
- // Check for a negative amount.
- if (!$this->negativeAmountAllowed && $amount < 0) {
- throw new InvalidRequestException('A negative amount is not allowed.');
- }
+ if ($amount === null) {
+ return null;
+ } elseif ($amount instanceof Money) {
+ $money = $amount;
+ } elseif (is_integer($amount)) {
+ $money = new Money($amount, $currency);
+ } else {
+ $moneyParser = new DecimalMoneyParser($this->getCurrencies());
- // Check for a zero amount.
- if (!$this->zeroAmountAllowed && $amount === 0.0) {
- throw new InvalidRequestException('A zero amount is not allowed.');
- }
+ $number = Number::fromString($amount);
// Check for rounding that may occur if too many significant decimal digits are supplied.
- $decimal_count = strlen(substr(strrchr(sprintf('%.8g', $amount), '.'), 1));
- if ($decimal_count > $this->getCurrencyDecimalPlaces()) {
+ $decimal_count = strlen($number->getFractionalPart());
+ $subunit = $this->getCurrencies()->subunitFor($currency);
+ if ($decimal_count > $subunit) {
throw new InvalidRequestException('Amount precision is too high for currency.');
}
- return $this->formatCurrency($amount);
+ $money = $moneyParser->parse((string) $number, $currency);
+ }
+
+ // Check for a negative amount.
+ if (!$this->negativeAmountAllowed && $money->isNegative()) {
+ throw new InvalidRequestException('A negative amount is not allowed.');
+ }
+
+ // Check for a zero amount.
+ if (!$this->zeroAmountAllowed && $money->isZero()) {
+ throw new InvalidRequestException('A zero amount is not allowed.');
+ }
+
+ return $money;
+ }
+
+ /**
+ * Validates and returns the formatted amount.
+ *
+ * @throws InvalidRequestException on any validation failure.
+ * @return string The amount formatted to the correct number of decimal places for the selected currency.
+ */
+ public function getAmount()
+ {
+ $money = $this->getMoney();
+
+ if ($money !== null) {
+ $moneyFormatter = new DecimalMoneyFormatter($this->getCurrencies());
+
+ return $moneyFormatter->format($money);
}
}
/**
* Sets the payment amount.
*
- * @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @param string|null $value
+ * @return $this
*/
public function setAmount($value)
{
- return $this->setParameter('amount', $value);
+ return $this->setParameter('amount', $value !== null ? (string) $value : null);
}
/**
@@ -362,7 +339,37 @@ public function setAmount($value)
*/
public function getAmountInteger()
{
- return (int) round($this->getAmount() * $this->getCurrencyDecimalFactor());
+ $money = $this->getMoney();
+
+ if ($money !== null) {
+ return (int) $money->getAmount();
+ }
+ }
+
+ /**
+ * Sets the payment amount as integer.
+ *
+ * @param int $value
+ * @return $this
+ */
+ public function setAmountInteger($value)
+ {
+ return $this->setParameter('amount', (int) $value);
+ }
+
+ /**
+ * Sets the payment amount as integer.
+ *
+ * @param Money $value
+ * @return $this
+ */
+ public function setMoney(Money $value)
+ {
+ $currency = $value->getCurrency()->getCode();
+
+ $this->setCurrency($currency);
+
+ return $this->setParameter('amount', $value);
}
/**
@@ -379,7 +386,7 @@ public function getCurrency()
* Sets the payment currency code.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setCurrency($value)
{
@@ -392,12 +399,18 @@ public function setCurrency($value)
/**
* Get the payment currency number.
*
- * @return integer
+ * @return string|null
*/
public function getCurrencyNumeric()
{
- if ($currency = Currency::find($this->getCurrency())) {
- return $currency->getNumeric();
+ if (! $this->getCurrency()) {
+ return null;
+ }
+
+ $currency = new Currency($this->getCurrency());
+
+ if ($this->getCurrencies()->contains($currency)) {
+ return (string) $this->getCurrencies()->numericCodeFor($currency);
}
}
@@ -408,31 +421,28 @@ public function getCurrencyNumeric()
*/
public function getCurrencyDecimalPlaces()
{
- if ($currency = Currency::find($this->getCurrency())) {
- return $currency->getDecimals();
+ if ($this->getCurrency()) {
+ $currency = new Currency($this->getCurrency());
+ if ($this->getCurrencies()->contains($currency)) {
+ return $this->getCurrencies()->subunitFor($currency);
+ }
}
return 2;
}
- private function getCurrencyDecimalFactor()
- {
- return pow(10, $this->getCurrencyDecimalPlaces());
- }
-
/**
* Format an amount for the payment currency.
*
+ * @param string $amount
* @return string
*/
public function formatCurrency($amount)
{
- return number_format(
- $amount,
- $this->getCurrencyDecimalPlaces(),
- '.',
- ''
- );
+ $money = $this->getMoney((string) $amount);
+ $formatter = new DecimalMoneyFormatter($this->getCurrencies());
+
+ return $formatter->format($money);
}
/**
@@ -449,7 +459,7 @@ public function getDescription()
* Sets the request description.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setDescription($value)
{
@@ -472,7 +482,7 @@ public function getTransactionId()
* Sets the transaction ID.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setTransactionId($value)
{
@@ -496,7 +506,7 @@ public function getTransactionReference()
* Sets the transaction reference.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setTransactionReference($value)
{
@@ -517,7 +527,7 @@ public function getItems()
* Set the items in this order
*
* @param ItemBag|array $items An array of items in this order
- * @return AbstractRequest
+ * @return $this
*/
public function setItems($items)
{
@@ -542,7 +552,7 @@ public function getClientIp()
* Sets the client IP address.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setClientIp($value)
{
@@ -563,7 +573,7 @@ public function getReturnUrl()
* Sets the request return URL.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setReturnUrl($value)
{
@@ -584,7 +594,7 @@ public function getCancelUrl()
* Sets the request cancel URL.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setCancelUrl($value)
{
@@ -605,7 +615,7 @@ public function getNotifyUrl()
* Sets the request notify URL.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setNotifyUrl($value)
{
@@ -632,7 +642,7 @@ public function getIssuer()
* the bank where an account is held (separate from the card brand).
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setIssuer($value)
{
@@ -659,7 +669,7 @@ public function getPaymentMethod()
* multiple payment providers with a single API.
*
* @param string $value
- * @return AbstractRequest Provides a fluent interface
+ * @return $this
*/
public function setPaymentMethod($value)
{
diff --git a/src/Omnipay/Common/Message/AbstractResponse.php b/src/Common/Message/AbstractResponse.php
similarity index 64%
rename from src/Omnipay/Common/Message/AbstractResponse.php
rename to src/Common/Message/AbstractResponse.php
index 27b63be5..d78f21a7 100644
--- a/src/Omnipay/Common/Message/AbstractResponse.php
+++ b/src/Common/Message/AbstractResponse.php
@@ -26,7 +26,6 @@
* // now do something with the $myResponse object, test for success, etc.
*
*
- * @see ResponseInterface
*/
abstract class AbstractResponse implements ResponseInterface
{
@@ -157,68 +156,111 @@ public function getTransactionId()
return null;
}
+ /**
+ * Gets the redirect target url.
+ *
+ * @return string
+ */
+ public function getRedirectUrl()
+ {
+ return null;
+ }
+
+ /**
+ * Get the required redirect method (either GET or POST).
+ *
+ * @return string
+ */
+ public function getRedirectMethod()
+ {
+ return 'GET';
+ }
+
+ /**
+ * Gets the redirect form data array, if the redirect method is POST.
+ *
+ * @return array
+ */
+ public function getRedirectData()
+ {
+ return [];
+ }
+
/**
* Automatically perform any required redirect
*
* This method is meant to be a helper for simple scenarios. If you want to customize the
* redirection page, just call the getRedirectUrl() and getRedirectData() methods directly.
*
- * @codeCoverageIgnore
- *
* @return void
*/
public function redirect()
{
$this->getRedirectResponse()->send();
- exit;
}
/**
- * @return HttpRedirectResponse
+ * @return HttpRedirectResponse|HttpResponse
*/
public function getRedirectResponse()
{
- if (!$this instanceof RedirectResponseInterface || !$this->isRedirect()) {
- throw new RuntimeException('This response does not support redirection.');
- }
+ $this->validateRedirect();
if ('GET' === $this->getRedirectMethod()) {
- return HttpRedirectResponse::create($this->getRedirectUrl());
- } elseif ('POST' === $this->getRedirectMethod()) {
- $hiddenFields = '';
- foreach ($this->getRedirectData() as $key => $value) {
- $hiddenFields .= sprintf(
- '',
- htmlentities($key, ENT_QUOTES, 'UTF-8', false),
- htmlentities($value, ENT_QUOTES, 'UTF-8', false)
- )."\n";
- }
-
- $output = '
+ return new HttpRedirectResponse($this->getRedirectUrl());
+ }
+
+ $hiddenFields = '';
+ foreach ($this->getRedirectData() as $key => $value) {
+ $hiddenFields .= sprintf(
+ '',
+ htmlentities($key, ENT_QUOTES, 'UTF-8', false),
+ htmlentities((string) $value, ENT_QUOTES, 'UTF-8', false)
+ )."\n";
+ }
+
+ $output = '
-
-
- Redirecting...
-
-
-
-
+
+
+ Redirecting...
+
+
+
+
';
- $output = sprintf(
- $output,
- htmlentities($this->getRedirectUrl(), ENT_QUOTES, 'UTF-8', false),
- $hiddenFields
- );
+ $output = sprintf(
+ $output,
+ htmlentities($this->getRedirectUrl(), ENT_QUOTES, 'UTF-8', false),
+ $hiddenFields
+ );
+
+ return new HttpResponse($output);
+ }
- return HttpResponse::create($output);
+ /**
+ * Validate that the current Response is a valid redirect.
+ *
+ * @return void
+ */
+ protected function validateRedirect()
+ {
+ if (!$this instanceof RedirectResponseInterface || !$this->isRedirect()) {
+ throw new RuntimeException('This response does not support redirection.');
}
- throw new RuntimeException('Invalid redirect method "'.$this->getRedirectMethod().'".');
+ if (empty($this->getRedirectUrl())) {
+ throw new RuntimeException('The given redirectUrl cannot be empty.');
+ }
+
+ if (!in_array($this->getRedirectMethod(), ['GET', 'POST'])) {
+ throw new RuntimeException('Invalid redirect method "'.$this->getRedirectMethod().'".');
+ }
}
}
diff --git a/src/Omnipay/Common/Message/FetchIssuersResponseInterface.php b/src/Common/Message/FetchIssuersResponseInterface.php
similarity index 93%
rename from src/Omnipay/Common/Message/FetchIssuersResponseInterface.php
rename to src/Common/Message/FetchIssuersResponseInterface.php
index e86d6a4a..5b22f425 100644
--- a/src/Omnipay/Common/Message/FetchIssuersResponseInterface.php
+++ b/src/Common/Message/FetchIssuersResponseInterface.php
@@ -15,8 +15,6 @@
* This happens when the gateway needs the customer to choose a
* card issuer.
*
- * @see ResponseInterface
- * @see Omnipay\Common\Issuer
*/
interface FetchIssuersResponseInterface extends ResponseInterface
{
diff --git a/src/Omnipay/Common/Message/FetchPaymentMethodsResponseInterface.php b/src/Common/Message/FetchPaymentMethodsResponseInterface.php
similarity index 93%
rename from src/Omnipay/Common/Message/FetchPaymentMethodsResponseInterface.php
rename to src/Common/Message/FetchPaymentMethodsResponseInterface.php
index 57ca8800..3aa3e65c 100644
--- a/src/Omnipay/Common/Message/FetchPaymentMethodsResponseInterface.php
+++ b/src/Common/Message/FetchPaymentMethodsResponseInterface.php
@@ -15,8 +15,6 @@
* This happens when the gateway needs the customer to choose a
* payment method.
*
- * @see ResponseInterface
- * @see Omnipay\Common\PaymentMethod
*/
interface FetchPaymentMethodsResponseInterface extends ResponseInterface
{
diff --git a/src/Omnipay/Common/Message/MessageInterface.php b/src/Common/Message/MessageInterface.php
similarity index 91%
rename from src/Omnipay/Common/Message/MessageInterface.php
rename to src/Common/Message/MessageInterface.php
index f472e2d0..44bb5e1d 100644
--- a/src/Omnipay/Common/Message/MessageInterface.php
+++ b/src/Common/Message/MessageInterface.php
@@ -9,7 +9,7 @@
* Message Interface
*
* This interface class defines the standard functions that any Omnipay message
- * interface needs to be able to provide.
+ * interface needs to be able to provide.
*/
interface MessageInterface
{
diff --git a/src/Omnipay/Common/Message/NotificationInterface.php b/src/Common/Message/NotificationInterface.php
similarity index 77%
rename from src/Omnipay/Common/Message/NotificationInterface.php
rename to src/Common/Message/NotificationInterface.php
index 14d53a90..41193a37 100755
--- a/src/Omnipay/Common/Message/NotificationInterface.php
+++ b/src/Common/Message/NotificationInterface.php
@@ -21,8 +21,8 @@ public function getTransactionReference();
/**
* Was the transaction successful?
*
- * @return string Transaction status, one of {@see STATUS_COMPLETED}, {@see #STATUS_PENDING},
- * or {@see #STATUS_FAILED}.
+ * @return string Transaction status, one of {@link NotificationInterface::STATUS_COMPLETED},
+ * {@link NotificationInterface::STATUS_PENDING}, or {@link NotificationInterface::STATUS_FAILED}.
*/
public function getTransactionStatus();
diff --git a/src/Omnipay/Common/Message/RedirectResponseInterface.php b/src/Common/Message/RedirectResponseInterface.php
similarity index 97%
rename from src/Omnipay/Common/Message/RedirectResponseInterface.php
rename to src/Common/Message/RedirectResponseInterface.php
index da585646..8ab7374f 100644
--- a/src/Omnipay/Common/Message/RedirectResponseInterface.php
+++ b/src/Common/Message/RedirectResponseInterface.php
@@ -13,7 +13,6 @@
* interface class with some extra functions relating to the
* specifics of a redirect response from the gateway.
*
- * @see ResponseInterface
*/
interface RedirectResponseInterface extends ResponseInterface
{
diff --git a/src/Omnipay/Common/Message/RequestInterface.php b/src/Common/Message/RequestInterface.php
similarity index 97%
rename from src/Omnipay/Common/Message/RequestInterface.php
rename to src/Common/Message/RequestInterface.php
index 3a47f823..cdce2ce5 100644
--- a/src/Omnipay/Common/Message/RequestInterface.php
+++ b/src/Common/Message/RequestInterface.php
@@ -11,7 +11,6 @@
* This interface class defines the standard functions that any Omnipay request
* interface needs to be able to provide. It is an extension of MessageInterface.
*
- * @see MessageInterface
*/
interface RequestInterface extends MessageInterface
{
diff --git a/src/Omnipay/Common/Message/ResponseInterface.php b/src/Common/Message/ResponseInterface.php
similarity index 98%
rename from src/Omnipay/Common/Message/ResponseInterface.php
rename to src/Common/Message/ResponseInterface.php
index 31081d98..caab8c8c 100644
--- a/src/Omnipay/Common/Message/ResponseInterface.php
+++ b/src/Common/Message/ResponseInterface.php
@@ -11,7 +11,6 @@
* This interface class defines the standard functions that any Omnipay response
* interface needs to be able to provide. It is an extension of MessageInterface.
*
- * @see MessageInterface
*/
interface ResponseInterface extends MessageInterface
{
diff --git a/src/Common/ParametersTrait.php b/src/Common/ParametersTrait.php
new file mode 100644
index 00000000..b3c1959a
--- /dev/null
+++ b/src/Common/ParametersTrait.php
@@ -0,0 +1,85 @@
+parameters->set($key, $value);
+
+ return $this;
+ }
+
+ /**
+ * Get one parameter.
+ *
+ * @param string $key Parameter key
+ * @return mixed A single parameter value.
+ */
+ protected function getParameter($key)
+ {
+ return $this->parameters->get($key);
+ }
+
+ /**
+ * Get all parameters.
+ *
+ * @return array An associative array of parameters.
+ */
+ public function getParameters()
+ {
+ return $this->parameters->all();
+ }
+
+ /**
+ * Initialize the object with parameters.
+ *
+ * If any unknown parameters passed, they will be ignored.
+ *
+ * @param array $parameters An associative array of parameters
+ * @return $this.
+ */
+ public function initialize(array $parameters = [])
+ {
+ $this->parameters = new ParameterBag;
+ Helper::initialize($this, $parameters);
+ return $this;
+ }
+
+ /**
+ * Validate the request.
+ *
+ * This method is called internally by gateways to avoid wasting time with an API call
+ * when the request is clearly invalid.
+ *
+ * @param string ... a variable length list of required parameters
+ * @throws InvalidRequestException
+ */
+ public function validate(...$args)
+ {
+ foreach ($args as $key) {
+ $value = $this->parameters->get($key);
+ if (! isset($value)) {
+ throw new InvalidRequestException("The $key parameter is required");
+ }
+ }
+ }
+}
diff --git a/src/Omnipay/Common/PaymentMethod.php b/src/Common/PaymentMethod.php
similarity index 96%
rename from src/Omnipay/Common/PaymentMethod.php
rename to src/Common/PaymentMethod.php
index 5f14b16e..2571eb32 100644
--- a/src/Omnipay/Common/PaymentMethod.php
+++ b/src/Common/PaymentMethod.php
@@ -10,7 +10,6 @@
*
* This class defines a payment method to be used in the Omnipay system.
*
- * @see Issuer
*/
class PaymentMethod
{
@@ -19,8 +18,6 @@ class PaymentMethod
* The ID of the payment method. Used as the payment method ID in the
* Issuer class.
*
- * @see Issuer
- *
* @var string
*/
protected $id;
diff --git a/src/Omnipay/Omnipay.php b/src/Omnipay.php
similarity index 85%
rename from src/Omnipay/Omnipay.php
rename to src/Omnipay.php
index fb064e7e..85903958 100644
--- a/src/Omnipay/Omnipay.php
+++ b/src/Omnipay.php
@@ -6,6 +6,7 @@
namespace Omnipay;
use Omnipay\Common\GatewayFactory;
+use Omnipay\Common\Http\ClientInterface;
/**
* Omnipay class
@@ -46,10 +47,10 @@
* @method static array find()
* @method static array getSupportedGateways()
* @codingStandardsIgnoreStart
- * @method static \Omnipay\Common\GatewayInterface create(string $class, \Guzzle\Http\ClientInterface $httpClient = null, \Symfony\Component\HttpFoundation\Request $httpRequest = null)
+ * @method static \Omnipay\Common\GatewayInterface create(string $class, ClientInterface $httpClient = null, \Symfony\Component\HttpFoundation\Request $httpRequest = null)
* @codingStandardsIgnoreEnd
*
- * @see Omnipay\Common\GatewayFactory
+ * @see \Omnipay\Common\GatewayFactory
*/
class Omnipay
{
@@ -70,11 +71,11 @@ class Omnipay
*/
public static function getFactory()
{
- if (is_null(static::$factory)) {
- static::$factory = new GatewayFactory;
+ if (is_null(self::$factory)) {
+ self::$factory = new GatewayFactory;
}
- return static::$factory;
+ return self::$factory;
}
/**
@@ -82,9 +83,9 @@ public static function getFactory()
*
* @param GatewayFactory $factory A GatewayFactory instance
*/
- public static function setFactory(GatewayFactory $factory = null)
+ public static function setFactory(?GatewayFactory $factory = null)
{
- static::$factory = $factory;
+ self::$factory = $factory;
}
/**
@@ -105,12 +106,12 @@ public static function setFactory(GatewayFactory $factory = null)
*
* @param string $method The factory method to invoke.
* @param array $parameters Parameters passed to the factory method.
- *
+ *
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
- $factory = static::getFactory();
+ $factory = self::getFactory();
return call_user_func_array(array($factory, $method), $parameters);
}
diff --git a/src/Omnipay/Common/Currency.php b/src/Omnipay/Common/Currency.php
deleted file mode 100644
index 7b71cc49..00000000
--- a/src/Omnipay/Common/Currency.php
+++ /dev/null
@@ -1,243 +0,0 @@
-code = $code;
- $this->numeric = $numeric;
- $this->decimals = $decimals;
- }
-
- /**
- * Get the three letter code for the currency
- *
- * @return string
- */
- public function getCode()
- {
- return $this->code;
- }
-
- /**
- * Get the numeric code for this currency
- *
- * @return string
- */
- public function getNumeric()
- {
- return $this->numeric;
- }
-
- /**
- * Get the number of decimal places for this currency
- *
- * @return int
- */
- public function getDecimals()
- {
- return $this->decimals;
- }
-
- /**
- * Find a specific currency
- *
- * @param string $code The three letter currency code
- * @return mixed A Currency object, or null if no currency was found
- */
- public static function find($code)
- {
- $code = strtoupper($code);
- $currencies = static::all();
-
- if (isset($currencies[$code])) {
- return new static($code, $currencies[$code]['numeric'], $currencies[$code]['decimals']);
- }
- }
-
- /**
- * Get an array of all supported currencies
- *
- * @return array
- */
- public static function all()
- {
- return array(
- 'AED' => array('numeric' => '784', 'decimals' => 2),
- 'AFN' => array('numeric' => '971', 'decimals' => 2),
- 'ALL' => array('numeric' => '008', 'decimals' => 2),
- 'AMD' => array('numeric' => '051', 'decimals' => 2),
- 'ANG' => array('numeric' => '532', 'decimals' => 2),
- 'AOA' => array('numeric' => '973', 'decimals' => 2),
- 'ARS' => array('numeric' => '032', 'decimals' => 2),
- 'AUD' => array('numeric' => '036', 'decimals' => 2),
- 'AWG' => array('numeric' => '533', 'decimals' => 2),
- 'AZN' => array('numeric' => '944', 'decimals' => 2),
- 'BAM' => array('numeric' => '977', 'decimals' => 2),
- 'BBD' => array('numeric' => '052', 'decimals' => 2),
- 'BDT' => array('numeric' => '050', 'decimals' => 2),
- 'BGN' => array('numeric' => '975', 'decimals' => 2),
- 'BHD' => array('numeric' => '048', 'decimals' => 3),
- 'BIF' => array('numeric' => '108', 'decimals' => 0),
- 'BMD' => array('numeric' => '060', 'decimals' => 2),
- 'BND' => array('numeric' => '096', 'decimals' => 2),
- 'BOB' => array('numeric' => '068', 'decimals' => 2),
- 'BRL' => array('numeric' => '986', 'decimals' => 2),
- 'BSD' => array('numeric' => '044', 'decimals' => 2),
- 'BTC' => array('numeric' => null, 'decimals' => 8),
- 'BTN' => array('numeric' => '064', 'decimals' => 2),
- 'BWP' => array('numeric' => '072', 'decimals' => 2),
- 'BYR' => array('numeric' => '974', 'decimals' => 0),
- 'BZD' => array('numeric' => '084', 'decimals' => 2),
- 'CAD' => array('numeric' => '124', 'decimals' => 2),
- 'CDF' => array('numeric' => '976', 'decimals' => 2),
- 'CHF' => array('numeric' => '756', 'decimals' => 2),
- 'CLP' => array('numeric' => '152', 'decimals' => 0),
- 'CNY' => array('numeric' => '156', 'decimals' => 2),
- 'COP' => array('numeric' => '170', 'decimals' => 2),
- 'CRC' => array('numeric' => '188', 'decimals' => 2),
- 'CUC' => array('numeric' => '931', 'decimals' => 2),
- 'CUP' => array('numeric' => '192', 'decimals' => 2),
- 'CVE' => array('numeric' => '132', 'decimals' => 2),
- 'CZK' => array('numeric' => '203', 'decimals' => 2),
- 'DJF' => array('numeric' => '262', 'decimals' => 0),
- 'DKK' => array('numeric' => '208', 'decimals' => 2),
- 'DOP' => array('numeric' => '214', 'decimals' => 2),
- 'DZD' => array('numeric' => '012', 'decimals' => 2),
- 'EGP' => array('numeric' => '818', 'decimals' => 2),
- 'ERN' => array('numeric' => '232', 'decimals' => 2),
- 'ETB' => array('numeric' => '230', 'decimals' => 2),
- 'EUR' => array('numeric' => '978', 'decimals' => 2),
- 'FJD' => array('numeric' => '242', 'decimals' => 2),
- 'FKP' => array('numeric' => '238', 'decimals' => 2),
- 'GBP' => array('numeric' => '826', 'decimals' => 2),
- 'GEL' => array('numeric' => '981', 'decimals' => 2),
- 'GHS' => array('numeric' => '936', 'decimals' => 2),
- 'GIP' => array('numeric' => '292', 'decimals' => 2),
- 'GMD' => array('numeric' => '270', 'decimals' => 2),
- 'GNF' => array('numeric' => '324', 'decimals' => 0),
- 'GTQ' => array('numeric' => '320', 'decimals' => 2),
- 'GYD' => array('numeric' => '328', 'decimals' => 2),
- 'HKD' => array('numeric' => '344', 'decimals' => 2),
- 'HNL' => array('numeric' => '340', 'decimals' => 2),
- 'HRK' => array('numeric' => '191', 'decimals' => 2),
- 'HTG' => array('numeric' => '332', 'decimals' => 2),
- 'HUF' => array('numeric' => '348', 'decimals' => 2),
- 'IDR' => array('numeric' => '360', 'decimals' => 2),
- 'ILS' => array('numeric' => '376', 'decimals' => 2),
- 'INR' => array('numeric' => '356', 'decimals' => 2),
- 'IQD' => array('numeric' => '368', 'decimals' => 3),
- 'IRR' => array('numeric' => '364', 'decimals' => 2),
- 'ISK' => array('numeric' => '352', 'decimals' => 0),
- 'JMD' => array('numeric' => '388', 'decimals' => 2),
- 'JOD' => array('numeric' => '400', 'decimals' => 3),
- 'JPY' => array('numeric' => '392', 'decimals' => 0),
- 'KES' => array('numeric' => '404', 'decimals' => 2),
- 'KGS' => array('numeric' => '417', 'decimals' => 2),
- 'KHR' => array('numeric' => '116', 'decimals' => 2),
- 'KMF' => array('numeric' => '174', 'decimals' => 0),
- 'KPW' => array('numeric' => '408', 'decimals' => 2),
- 'KRW' => array('numeric' => '410', 'decimals' => 0),
- 'KWD' => array('numeric' => '414', 'decimals' => 3),
- 'KYD' => array('numeric' => '136', 'decimals' => 2),
- 'KZT' => array('numeric' => '398', 'decimals' => 2),
- 'LAK' => array('numeric' => '418', 'decimals' => 0),
- 'LBP' => array('numeric' => '422', 'decimals' => 2),
- 'LKR' => array('numeric' => '144', 'decimals' => 2),
- 'LRD' => array('numeric' => '430', 'decimals' => 2),
- 'LSL' => array('numeric' => '426', 'decimals' => 2),
- 'LYD' => array('numeric' => '434', 'decimals' => 3),
- 'MAD' => array('numeric' => '504', 'decimals' => 2),
- 'MDL' => array('numeric' => '498', 'decimals' => 2),
- 'MGA' => array('numeric' => '969', 'decimals' => 0),
- 'MKD' => array('numeric' => '807', 'decimals' => 2),
- 'MMK' => array('numeric' => '104', 'decimals' => 2),
- 'MNT' => array('numeric' => '496', 'decimals' => 2),
- 'MOP' => array('numeric' => '446', 'decimals' => 2),
- 'MRO' => array('numeric' => '478', 'decimals' => 0),
- 'MUR' => array('numeric' => '480', 'decimals' => 2),
- 'MVR' => array('numeric' => '462', 'decimals' => 2),
- 'MWK' => array('numeric' => '454', 'decimals' => 2),
- 'MXN' => array('numeric' => '484', 'decimals' => 2),
- 'MYR' => array('numeric' => '458', 'decimals' => 2),
- 'MZN' => array('numeric' => '943', 'decimals' => 2),
- 'NAD' => array('numeric' => '516', 'decimals' => 2),
- 'NGN' => array('numeric' => '566', 'decimals' => 2),
- 'NIO' => array('numeric' => '558', 'decimals' => 2),
- 'NOK' => array('numeric' => '578', 'decimals' => 2),
- 'NPR' => array('numeric' => '524', 'decimals' => 2),
- 'NZD' => array('numeric' => '554', 'decimals' => 2),
- 'OMR' => array('numeric' => '512', 'decimals' => 3),
- 'PAB' => array('numeric' => '590', 'decimals' => 2),
- 'PEN' => array('numeric' => '604', 'decimals' => 2),
- 'PGK' => array('numeric' => '598', 'decimals' => 2),
- 'PHP' => array('numeric' => '608', 'decimals' => 2),
- 'PKR' => array('numeric' => '586', 'decimals' => 2),
- 'PLN' => array('numeric' => '985', 'decimals' => 2),
- 'PYG' => array('numeric' => '600', 'decimals' => 0),
- 'QAR' => array('numeric' => '634', 'decimals' => 2),
- 'RON' => array('numeric' => '946', 'decimals' => 2),
- 'RSD' => array('numeric' => '941', 'decimals' => 0),
- 'RUB' => array('numeric' => '643', 'decimals' => 2),
- 'RWF' => array('numeric' => '646', 'decimals' => 0),
- 'SAR' => array('numeric' => '682', 'decimals' => 2),
- 'SBD' => array('numeric' => '090', 'decimals' => 2),
- 'SCR' => array('numeric' => '690', 'decimals' => 2),
- 'SDG' => array('numeric' => '938', 'decimals' => 2),
- 'SEK' => array('numeric' => '752', 'decimals' => 2),
- 'SGD' => array('numeric' => '702', 'decimals' => 2),
- 'SHP' => array('numeric' => '654', 'decimals' => 2),
- 'SLL' => array('numeric' => '694', 'decimals' => 2),
- 'SOS' => array('numeric' => '706', 'decimals' => 2),
- 'SRD' => array('numeric' => '968', 'decimals' => 2),
- 'SSP' => array('numeric' => '728', 'decimals' => 2),
- 'STD' => array('numeric' => '678', 'decimals' => 2),
- 'SYP' => array('numeric' => '760', 'decimals' => 2),
- 'SZL' => array('numeric' => '748', 'decimals' => 2),
- 'THB' => array('numeric' => '764', 'decimals' => 2),
- 'TJS' => array('numeric' => '972', 'decimals' => 2),
- 'TMT' => array('numeric' => '934', 'decimals' => 2),
- 'TND' => array('numeric' => '788', 'decimals' => 3),
- 'TOP' => array('numeric' => '776', 'decimals' => 2),
- 'TRY' => array('numeric' => '949', 'decimals' => 2),
- 'TTD' => array('numeric' => '780', 'decimals' => 2),
- 'TWD' => array('numeric' => '901', 'decimals' => 2),
- 'TZS' => array('numeric' => '834', 'decimals' => 2),
- 'UAH' => array('numeric' => '980', 'decimals' => 2),
- 'UGX' => array('numeric' => '800', 'decimals' => 0),
- 'USD' => array('numeric' => '840', 'decimals' => 2),
- 'UYU' => array('numeric' => '858', 'decimals' => 2),
- 'UZS' => array('numeric' => '860', 'decimals' => 2),
- 'VEF' => array('numeric' => '937', 'decimals' => 2),
- 'VND' => array('numeric' => '704', 'decimals' => 0),
- 'VUV' => array('numeric' => '548', 'decimals' => 0),
- 'WST' => array('numeric' => '882', 'decimals' => 2),
- 'XAF' => array('numeric' => '950', 'decimals' => 0),
- 'XCD' => array('numeric' => '951', 'decimals' => 2),
- 'XOF' => array('numeric' => '952', 'decimals' => 0),
- 'XPF' => array('numeric' => '953', 'decimals' => 0),
- 'YER' => array('numeric' => '886', 'decimals' => 2),
- 'ZAR' => array('numeric' => '710', 'decimals' => 2),
- 'ZMW' => array('numeric' => '967', 'decimals' => 2),
- );
- }
-}
diff --git a/tests/Omnipay/Common/AbstractGatewayTest.php b/tests/Common/AbstractGatewayTest.php
similarity index 84%
rename from tests/Omnipay/Common/AbstractGatewayTest.php
rename to tests/Common/AbstractGatewayTest.php
index 71cb83fc..384e09e8 100755
--- a/tests/Omnipay/Common/AbstractGatewayTest.php
+++ b/tests/Common/AbstractGatewayTest.php
@@ -3,33 +3,38 @@
namespace Omnipay\Common;
use Mockery as m;
+use Omnipay\Common\Http\Client;
use Omnipay\Common\Message\AbstractRequest;
use Omnipay\Tests\TestCase;
use Symfony\Component\HttpFoundation\ParameterBag;
class AbstractGatewayTest extends TestCase
{
- public function setUp()
+ /** @var \Omnipay\Common\AbstractGateway */
+ protected $gateway;
+
+ public function setUp() : void
{
- $this->gateway = m::mock('\Omnipay\Common\AbstractGateway')->makePartial();
+ $this->gateway = new AbstractGatewayTest_MockAbstractGateway();
$this->gateway->initialize();
}
public function testConstruct()
{
$this->gateway = new AbstractGatewayTest_MockAbstractGateway;
- $this->assertInstanceOf('\Guzzle\Http\Client', $this->gateway->getProtectedHttpClient());
+ $this->assertInstanceOf(Client::class, $this->gateway->getProtectedHttpClient());
$this->assertInstanceOf('\Symfony\Component\HttpFoundation\Request', $this->gateway->getProtectedHttpRequest());
$this->assertSame(array(), $this->gateway->getParameters());
}
public function testGetShortName()
{
- $this->assertSame('\\'.get_class($this->gateway), $this->gateway->getShortName());
+ $this->assertSame('Common_AbstractGatewayTest_MockAbstract', $this->gateway->getShortName());
}
public function testInitializeDefaults()
{
+ $this->gateway = m::mock('\Omnipay\Common\AbstractGateway')->makePartial();
$defaults = array(
'currency' => 'AUD', // fixed default type
'username' => array('joe', 'fred'), // enum default type
@@ -48,6 +53,7 @@ public function testInitializeDefaults()
public function testInitializeParameters()
{
+ $this->gateway = m::mock('\Omnipay\Common\AbstractGateway')->makePartial();
$this->gateway->shouldReceive('getDefaultParameters')->once()
->andReturn(array('currency' => 'AUD'));
@@ -71,6 +77,15 @@ public function testGetParameters()
$this->assertSame(array('testMode' => true), $this->gateway->getParameters());
}
+ public function testSetSetParameter()
+ {
+ $token = 'foobar';
+
+ $this->gateway->setParameter('token', $token);
+
+ $this->assertEquals($token, $this->gateway->getParameter('token'));
+ }
+
public function testTestMode()
{
$this->assertSame($this->gateway, $this->gateway->setTestMode(true));
@@ -108,6 +123,11 @@ public function testSupportsCompletePurchase()
$this->assertFalse($this->gateway->supportsCompletePurchase());
}
+ public function testSupportsFetchTransaction()
+ {
+ $this->assertFalse($this->gateway->supportsFetchTransaction());
+ }
+
public function testSupportsRefund()
{
$this->assertFalse($this->gateway->supportsRefund());
diff --git a/tests/Omnipay/Common/CreditCardTest.php b/tests/Common/CreditCardTest.php
similarity index 93%
rename from tests/Omnipay/Common/CreditCardTest.php
rename to tests/Common/CreditCardTest.php
index b829369a..bc643e4f 100644
--- a/tests/Omnipay/Common/CreditCardTest.php
+++ b/tests/Common/CreditCardTest.php
@@ -2,6 +2,7 @@
namespace Omnipay\Common;
+use Omnipay\Common\Exception\InvalidRequestException;
use Omnipay\Tests\TestCase;
class CreditCardTest extends TestCase
@@ -9,7 +10,7 @@ class CreditCardTest extends TestCase
/** @var CreditCard */
private $card;
- public function setUp()
+ public function setUp() : void
{
$this->card = new CreditCard;
$this->card->setNumber('4111111111111111');
@@ -50,57 +51,55 @@ public function testGetParamters()
$this->assertSame(2016, $parameters['expiryYear']);
}
+ /**
+ * @doesNotPerformAssertions
+ */
public function testValidateFixture()
{
$this->card->validate();
}
- /**
- * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage The number parameter is required
- */
public function testValidateNumberRequired()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('The credit card number is required');
+
$this->card->setNumber(null);
$this->card->validate();
}
- /**
- * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage The expiryMonth parameter is required
- */
public function testValidateExpiryMonthRequired()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('The expiration month is required');
+
$this->card->setExpiryMonth(null);
$this->card->validate();
}
- /**
- * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage The expiryYear parameter is required
- */
public function testValidateExpiryYearRequired()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('The expiration year is required');
+
$this->card->setExpiryYear(null);
$this->card->validate();
}
- /**
- * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage Card has expired
- */
public function testValidateExpiryDate()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('Card has expired');
+
$this->card->setExpiryYear(gmdate('Y')-1);
$this->card->validate();
}
- /**
- * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage Card number is invalid
- */
public function testValidateNumber()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('Card number is invalid');
+
$this->card->setNumber('4111111111111110');
$this->card->validate();
}
@@ -108,7 +107,7 @@ public function testValidateNumber()
public function testGetSupportedBrands()
{
$brands = $this->card->getSupportedBrands();
- $this->assertInternalType('array', $brands);
+ $this->assertIsArray($brands);
$this->assertArrayHasKey(CreditCard::BRAND_VISA, $brands);
}
@@ -358,6 +357,13 @@ public function testShouldReturnTrack2()
$this->assertEquals(';4242424242424242=15201269999944401?', $actual);
}
+ public function testShouldReturnNoTrack()
+ {
+ $this->card->setTracks(null);
+ $actual = $this->card->getTrack2();
+ $this->assertNull($actual);
+ }
+
public function testIssueNumber()
{
$this->card->setIssueNumber('12');
@@ -660,22 +666,20 @@ public function testGender()
$this->assertEquals('female', $this->card->getGender());
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage Card number is invalid
- */
public function testInvalidLuhn()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('Card number is invalid');
+
$this->card->setNumber('43');
$this->card->validate();
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidCreditCardException
- * @expectedExceptionMessage Card number should have 12 to 19 digits
- */
public function testInvalidShortCard()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidCreditCardException::class);
+ $this->expectExceptionMessage('Card number should have 12 to 19 digits');
+
$this->card->setNumber('4440');
$this->card->validate();
}
diff --git a/tests/Omnipay/Common/Exception/BadMethodCallExceptionTest.php b/tests/Common/Exception/BadMethodCallExceptionTest.php
similarity index 100%
rename from tests/Omnipay/Common/Exception/BadMethodCallExceptionTest.php
rename to tests/Common/Exception/BadMethodCallExceptionTest.php
diff --git a/tests/Omnipay/Common/Exception/InvalidCreditCardExceptionTest.php b/tests/Common/Exception/InvalidCreditCardExceptionTest.php
similarity index 100%
rename from tests/Omnipay/Common/Exception/InvalidCreditCardExceptionTest.php
rename to tests/Common/Exception/InvalidCreditCardExceptionTest.php
diff --git a/tests/Omnipay/Common/Exception/InvalidRequestExceptionTest.php b/tests/Common/Exception/InvalidRequestExceptionTest.php
similarity index 100%
rename from tests/Omnipay/Common/Exception/InvalidRequestExceptionTest.php
rename to tests/Common/Exception/InvalidRequestExceptionTest.php
diff --git a/tests/Omnipay/Common/Exception/InvalidResponseExceptionTest.php b/tests/Common/Exception/InvalidResponseExceptionTest.php
similarity index 100%
rename from tests/Omnipay/Common/Exception/InvalidResponseExceptionTest.php
rename to tests/Common/Exception/InvalidResponseExceptionTest.php
diff --git a/tests/Omnipay/Common/Exception/RuntimeExceptionTest.php b/tests/Common/Exception/RuntimeExceptionTest.php
similarity index 100%
rename from tests/Omnipay/Common/Exception/RuntimeExceptionTest.php
rename to tests/Common/Exception/RuntimeExceptionTest.php
diff --git a/tests/Omnipay/Common/GatewayFactoryTest.php b/tests/Common/GatewayFactoryTest.php
similarity index 51%
rename from tests/Omnipay/Common/GatewayFactoryTest.php
rename to tests/Common/GatewayFactoryTest.php
index 22556c86..45cccb43 100644
--- a/tests/Omnipay/Common/GatewayFactoryTest.php
+++ b/tests/Common/GatewayFactoryTest.php
@@ -7,12 +7,15 @@
class GatewayFactoryTest extends TestCase
{
- public static function setUpBeforeClass()
+ /** @var GatewayFactory */
+ protected $factory;
+
+ public static function setUpBeforeClass() : void
{
m::mock('alias:Omnipay\\SpareChange\\TestGateway');
}
- public function setUp()
+ public function setUp() : void
{
$this->factory = new GatewayFactory;
}
@@ -41,30 +44,6 @@ public function testRegisterExistingGateway()
$this->assertSame(array('Milky', 'Bar'), $this->factory->all());
}
- public function testFindRegistersAvailableGateways()
- {
- $this->factory = m::mock('Omnipay\Common\GatewayFactory[getSupportedGateways]');
- $this->factory->shouldReceive('getSupportedGateways')->once()
- ->andReturn(array('SpareChange_Test'));
-
- $gateways = $this->factory->find();
-
- $this->assertContains('SpareChange_Test', $gateways);
- $this->assertContains('SpareChange_Test', $this->factory->all());
- }
-
- public function testFindIgnoresUnavailableGateways()
- {
- $this->factory = m::mock('Omnipay\Common\GatewayFactory[getSupportedGateways]');
- $this->factory->shouldReceive('getSupportedGateways')->once()
- ->andReturn(array('SpareChange_Gone'));
-
- $gateways = $this->factory->find();
-
- $this->assertEmpty($gateways);
- $this->assertEmpty($this->factory->all());
- }
-
public function testCreateShortName()
{
$gateway = $this->factory->create('SpareChange_Test');
@@ -77,19 +56,11 @@ public function testCreateFullyQualified()
$this->assertInstanceOf('\\Omnipay\\SpareChange\\TestGateway', $gateway);
}
- /**
- * @expectedException \Omnipay\Common\Exception\RuntimeException
- * @expectedExceptionMessage Class '\Omnipay\Invalid\Gateway' not found
- */
public function testCreateInvalid()
{
- $gateway = $this->factory->create('Invalid');
- }
-
- public function testGetSupportedGateways()
- {
- $gateways = $this->factory->getSupportedGateways();
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage("Class '\Omnipay\Invalid\Gateway' not found");
- $this->assertContains('Stripe', $gateways);
+ $gateway = $this->factory->create('Invalid');
}
}
diff --git a/tests/Omnipay/Common/HelperTest.php b/tests/Common/HelperTest.php
similarity index 63%
rename from tests/Omnipay/Common/HelperTest.php
rename to tests/Common/HelperTest.php
index 003d1571..a2e2d012 100644
--- a/tests/Omnipay/Common/HelperTest.php
+++ b/tests/Common/HelperTest.php
@@ -43,18 +43,18 @@ public function testValidateLuhnNull()
$this->assertTrue($result);
}
+ /**
+ * @doesNotPerformAssertions
+ */
public function testInitializeIgnoresNull()
{
$target = m::mock();
Helper::initialize($target, null);
}
- public function testInitializeIgnoresString()
- {
- $target = m::mock();
- Helper::initialize($target, 'invalid');
- }
-
+ /**
+ * @doesNotPerformAssertions
+ */
public function testInitializeCallsSetters()
{
$target = m::mock('\Omnipay\Common\CreditCard');
@@ -64,6 +64,9 @@ public function testInitializeCallsSetters()
Helper::initialize($target, array('name' => 'adrian', 'number' => '1234'));
}
+ /**
+ * @doesNotPerformAssertions
+ */
public function testInitializeIgnoresInvalidParameters()
{
$target = m::mock('\Omnipay\Common\CreditCard');
@@ -141,92 +144,9 @@ public function testGetGatewayClassNameUnderscoreNamespace()
$this->assertEquals('\\Omnipay\\PayPal\\ExpressGateway', $class);
}
- /**
- * Some valid toFloat() inputs.
- */
- public function testToFloatFromFloat()
- {
- $shortName = Helper::toFloat(1.99);
- $this->assertSame(1.99, $shortName);
- }
-
- public function testToFloatFromInt()
- {
- $shortName = Helper::toFloat(199);
- $this->assertSame(199.0, $shortName);
- }
-
- public function testToFloatFromStringDecimal()
- {
- $shortName = Helper::toFloat("1.99");
- $this->assertSame(1.99, $shortName);
- }
-
- public function testToFloatFromStringRedunantZeroes()
- {
- $shortName = Helper::toFloat("000009.99900000000");
- $this->assertSame(9.999, $shortName);
- }
-
- public function testToFloatFromStringEmptyDecimal()
- {
- $shortName = Helper::toFloat("1.");
- $this->assertSame(1.0, $shortName);
- }
-
- public function testToFloatFromStringInt()
- {
- $shortName = Helper::toFloat("199");
- $this->assertSame(199.0, $shortName);
- }
-
- public function testToFloatFromStringIntNegative()
- {
- $shortName = Helper::toFloat("-199");
- $this->assertSame(-199.0, $shortName);
- }
-
- /**
- * Some invalid toFloat() inputs.
- */
-
- /**
- * The number MUST always start with a digit.
- * This is arguably an arbitrary rule that perhaps does not need
- * to be enforced.
- *
- * @expectedException \InvalidArgumentException
- * @expectedExceptionMessage String is not a valid decimal number
- */
- public function testToFloatFromStringEmptyIntegerPart()
- {
- $shortName = Helper::toFloat(".99");
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @expectedExceptionMessage String is not a valid decimal number
- */
- public function testToFloatFromStringTwoDecimalPoints()
- {
- $shortName = Helper::toFloat("1.99.");
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @expectedExceptionMessage String is not a valid decimal number
- */
- public function testToFloatFromStringWrongDecimalPoints()
- {
- $shortName = Helper::toFloat("1,99");
- }
-
- /**
- * @expectedException \InvalidArgumentException
- * @expectedExceptionMessage Data type is not a valid decimal number
- */
- public function testToFloatFromBoolean()
+ public function testGetGatewayClassNameFQCN()
{
- $shortName = Helper::toFloat(false);
+ $class = Helper::getGatewayClassName('Omnipay\Stripe\PaymentIntentsGateway');
+ $this->assertEquals('Omnipay\Stripe\PaymentIntentsGateway', $class);
}
}
diff --git a/tests/Common/Http/ClientTest.php b/tests/Common/Http/ClientTest.php
new file mode 100644
index 00000000..b2534824
--- /dev/null
+++ b/tests/Common/Http/ClientTest.php
@@ -0,0 +1,133 @@
+shouldReceive('createRequest')->withArgs([
+ 'GET',
+ '/path',
+ [],
+ null,
+ '1.1',
+ ])->andReturn($request);
+
+ $mockClient->shouldReceive('sendRequest')
+ ->with($request)
+ ->andReturn($response)
+ ->once();
+
+ $this->assertSame($response, $client->request('GET', '/path'));
+
+ }
+
+ public function testSendException()
+ {
+ $mockClient = m::mock(HttpClient::class);
+ $mockFactory = m::mock(RequestFactory::class);
+ $client = new Client($mockClient, $mockFactory);
+
+ $request = new Request('GET', '/path');
+ $response = new Response();
+
+ $mockFactory->shouldReceive('createRequest')->withArgs([
+ 'GET',
+ '/path',
+ [],
+ null,
+ '1.1',
+ ])->andReturn($request);
+
+ $mockClient->shouldReceive('sendRequest')
+ ->with($request)
+ ->andThrow(new \Exception('Something went wrong'));
+
+ $this->expectException(\Omnipay\Common\Http\Exception\RequestException::class);
+ $this->expectExceptionMessage('Something went wrong');
+
+ $client->request('GET', '/path');
+ }
+
+ public function testSendNetworkException()
+ {
+ $mockClient = m::mock(HttpClient::class);
+ $mockFactory = m::mock(RequestFactory::class);
+ $client = new Client($mockClient, $mockFactory);
+
+ $request = new Request('GET', '/path');
+ $response = new Response();
+
+ $mockFactory->shouldReceive('createRequest')->withArgs([
+ 'GET',
+ '/path',
+ [],
+ null,
+ '1.1',
+ ])->andReturn($request);
+
+ $mockClient->shouldReceive('sendRequest')
+ ->with($request)
+ ->andThrow(new NetworkException('Something went wrong', $request));
+
+ $this->expectException(\Omnipay\Common\Http\Exception\NetworkException::class);
+ $this->expectExceptionMessage('Something went wrong');
+
+ $client->request('GET', '/path');
+ }
+
+ public function testSendExceptionGetRequest()
+ {
+ $mockClient = m::mock(HttpClient::class);
+ $mockFactory = m::mock(RequestFactory::class);
+ $client = new Client($mockClient, $mockFactory);
+
+ $request = new Request('GET', '/path');
+ $response = new Response();
+
+ $mockFactory->shouldReceive('createRequest')->withArgs([
+ 'GET',
+ '/path',
+ [],
+ null,
+ '1.1',
+ ])->andReturn($request);
+
+ $exception = new \Exception('Something went wrong');
+
+ $mockClient->shouldReceive('sendRequest')
+ ->with($request)
+ ->andThrow($exception);
+
+ $this->expectException(\Omnipay\Common\Http\Exception\RequestException::class);
+ $this->expectExceptionMessage('Something went wrong');
+
+
+ try {
+ $client->request('GET', '/path');
+ } catch (RequestException $e) {
+ $this->assertSame($request, $e->getRequest());
+ $this->assertSame($exception, $e->getPrevious());
+
+ throw $e;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Common/Http/ExceptionTest.php b/tests/Common/Http/ExceptionTest.php
new file mode 100644
index 00000000..527bd544
--- /dev/null
+++ b/tests/Common/Http/ExceptionTest.php
@@ -0,0 +1,22 @@
+assertSame($request, $exception->getRequest());
+ $this->assertSame('Something went wrong', $exception->getMessage());
+ $this->assertSame($previous, $exception->getPrevious());
+ }
+}
\ No newline at end of file
diff --git a/tests/Omnipay/Common/IssuerTest.php b/tests/Common/IssuerTest.php
similarity index 100%
rename from tests/Omnipay/Common/IssuerTest.php
rename to tests/Common/IssuerTest.php
diff --git a/tests/Omnipay/Common/ItemBagTest.php b/tests/Common/ItemBagTest.php
similarity index 95%
rename from tests/Omnipay/Common/ItemBagTest.php
rename to tests/Common/ItemBagTest.php
index ac865e0c..460690ee 100644
--- a/tests/Omnipay/Common/ItemBagTest.php
+++ b/tests/Common/ItemBagTest.php
@@ -6,7 +6,10 @@
class ItemBagTest extends TestCase
{
- public function setUp()
+ /** @var ItemBag */
+ protected $bag;
+
+ public function setUp() : void
{
$this->bag = new ItemBag;
}
diff --git a/tests/Omnipay/Common/ItemTest.php b/tests/Common/ItemTest.php
similarity index 94%
rename from tests/Omnipay/Common/ItemTest.php
rename to tests/Common/ItemTest.php
index 8c008b51..c653e646 100644
--- a/tests/Omnipay/Common/ItemTest.php
+++ b/tests/Common/ItemTest.php
@@ -6,7 +6,10 @@
class ItemTest extends TestCase
{
- public function setUp()
+ /** @var Item */
+ protected $item;
+
+ public function setUp() : void
{
$this->item = new Item;
}
diff --git a/tests/Omnipay/Common/Message/AbstractRequestTest.php b/tests/Common/Message/AbstractRequestTest.php
similarity index 80%
rename from tests/Omnipay/Common/Message/AbstractRequestTest.php
rename to tests/Common/Message/AbstractRequestTest.php
index 0e07a984..8f196e34 100644
--- a/tests/Omnipay/Common/Message/AbstractRequestTest.php
+++ b/tests/Common/Message/AbstractRequestTest.php
@@ -3,15 +3,20 @@
namespace Omnipay\Common\Message;
use Mockery as m;
+use Money\Currency;
+use Money\Money;
use Omnipay\Common\CreditCard;
use Omnipay\Common\ItemBag;
use Omnipay\Tests\TestCase;
class AbstractRequestTest extends TestCase
{
- public function setUp()
+ /** @var AbstractRequest */
+ protected $request;
+
+ public function setUp(): void
{
- $this->request = m::mock('\Omnipay\Common\Message\AbstractRequest')->makePartial();
+ $this->request = new AbstractRequestTest_MockAbstractRequest($this->getHttpClient(), $this->getHttpRequest());
$this->request->initialize();
}
@@ -43,12 +48,12 @@ public function testInitializeWithParams()
$this->assertSame('1.23', $this->request->getAmount());
}
- /**
- * @expectedException \Omnipay\Common\Exception\RuntimeException
- * @expectedExceptionMessage Request cannot be modified after it has been sent!
- */
public function testInitializeAfterRequestSent()
{
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage("Request cannot be modified after it has been sent!");
+
+
$this->request = new AbstractRequestTest_MockAbstractRequest($this->getHttpClient(), $this->getHttpRequest());
$this->request->send();
@@ -115,12 +120,11 @@ public function testAmountZeroString()
$this->assertSame('0.00', $this->request->getAmount());
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- * @expectedExceptionMessage A zero amount is not allowed.
- */
public function testAmountZeroNotAllowed()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class);
+ $this->expectExceptionMessage('A zero amount is not allowed.');
+
$this->changeProtectedProperty('zeroAmountAllowed', false);
$this->request->setAmount('0.00');
$this->request->getAmount();
@@ -149,14 +153,24 @@ public function testAmountPrecision()
$this->assertSame('0.01', $this->request->getAmount());
}
+ // See https://github.com/thephpleague/omnipay-common/issues/143
+ public function testAmountPrecisionLargeNumbers()
+ {
+ $this->request->setCurrency('VND');
+
+ $this->assertSame($this->request, $this->request->setAmount('103500000'));
+ $this->assertSame('103500000', $this->request->getAmount());
+ }
+
/**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
*
* We still want to catch obvious fractions of the minor units that are
* not precision errors at a much lower level.
*/
public function testAmountPrecisionTooHigh()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class);
+
$this->assertSame($this->request, $this->request->setAmount('123.005'));
$this->assertSame('123.005', $this->request->getAmount());
}
@@ -168,42 +182,33 @@ public function testGetAmountNoDecimals()
$this->assertSame('1366', $this->request->getAmount());
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
public function testGetAmountNoDecimalsRounding()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class);
+
// There will not be any rounding; the amount is sent as requested or not at all.
$this->assertSame($this->request, $this->request->setAmount('136.5'));
$this->assertSame($this->request, $this->request->setCurrency('JPY'));
$this->request->getAmount();
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
- public function testAmountWithIntThrowsException()
+ public function testGetAmountInteger()
{
- // ambiguous value, avoid errors upgrading from v0.9
- $this->assertSame($this->request, $this->request->setAmount(10));
- $this->request->getAmount();
+ $this->assertSame($this->request, $this->request->setAmount('13.66'));
+ $this->assertSame(1366, $this->request->getAmountInteger());
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
- public function testAmountWithIntStringThrowsException()
+ public function testGetAmountIntegerNull()
{
- // ambiguous value, avoid errors upgrading from v0.9
- // Some currencies only take integers, so an integer (in a string) should be valid.
- $this->assertSame($this->request, $this->request->setAmount('10'));
- $this->request->getAmount();
+ $this->assertSame($this->request, $this->request->setAmount(null));
+ $this->assertSame(null, $this->request->getAmountInteger());
}
- public function testGetAmountInteger()
+ public function testSetAmountInteger()
{
- $this->assertSame($this->request, $this->request->setAmount('13.66'));
+ $this->assertSame($this->request, $this->request->setAmountInteger(1366));
$this->assertSame(1366, $this->request->getAmountInteger());
+ $this->assertSame('13.66', $this->request->getAmount());
}
public function testGetAmountIntegerNoDecimals()
@@ -213,51 +218,53 @@ public function testGetAmountIntegerNoDecimals()
$this->assertSame(1366, $this->request->getAmountInteger());
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
public function testAmountThousandsSepThrowsException()
{
+ $this->expectException(\InvalidArgumentException::class);
+
$this->assertSame($this->request, $this->request->setAmount('1,234.00'));
$this->request->getAmount();
}
/**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
+ * @expectedException \InvalidArgumentException
*/
public function testAmountInvalidFormatThrowsException()
{
- $this->assertSame($this->request, $this->request->setAmount('1.234.00'));
- $this->request->getAmount();
- }
+ $this->expectException(\InvalidArgumentException::class);
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
- public function testAmountInvalidTypeThrowsException()
- {
- $this->assertSame($this->request, $this->request->setAmount(true));
+ $this->assertSame($this->request, $this->request->setAmount('1.234.00'));
$this->request->getAmount();
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
public function testAmountNegativeStringThrowsException()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class);
+
$this->assertSame($this->request, $this->request->setAmount('-123.00'));
$this->request->getAmount();
}
- /**
- * @expectedException Omnipay\Common\Exception\InvalidRequestException
- */
public function testAmountNegativeFloatThrowsException()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class);
+
$this->assertSame($this->request, $this->request->setAmount(-123.00));
$this->request->getAmount();
}
+ public function testMoney()
+ {
+ $money = new Money(12345, new Currency('EUR'));
+ $this->assertSame($this->request, $this->request->setMoney($money));
+
+ $this->request->validate('amount', 'currency');
+
+ $this->assertSame('123.45', $this->request->getAmount());
+ $this->assertSame(12345, $this->request->getAmountInteger());
+ $this->assertSame('EUR', $this->request->getCurrency());
+ }
+
public function testCurrency()
{
$this->assertSame($this->request, $this->request->setCurrency('USD'));
@@ -282,17 +289,33 @@ public function testCurrencyNumeric()
$this->assertSame('840', $this->request->getCurrencyNumeric());
}
+ public function testCurrencyNumericNull()
+ {
+ $this->assertSame($this->request, $this->request->setCurrency(null));
+ $this->assertSame(null, $this->request->getCurrencyNumeric());
+ }
+
+ public function testCurrencyNumericUnkown()
+ {
+ $this->assertSame($this->request, $this->request->setCurrency('UNKNOWN'));
+ $this->assertSame(null, $this->request->getCurrencyNumeric());
+ }
+
public function testCurrencyDecimals()
{
$this->assertSame($this->request, $this->request->setCurrency('JPY'));
$this->assertSame(0, $this->request->getCurrencyDecimalPlaces());
}
+ public function testCurrencyDecimalsDefault()
+ {
+ $this->assertSame(2, $this->request->getCurrencyDecimalPlaces());
+ }
+
public function testFormatCurrency()
{
$this->assertSame('1234.00', $this->request->formatCurrency(1234));
}
-
public function testFormatCurrencyNoDecimals()
{
$this->request->setCurrency('JPY');
@@ -398,12 +421,11 @@ public function testGetParameters()
$this->assertEquals($expected, $this->request->getParameters());
}
- /**
- * @expectedException \Omnipay\Common\Exception\RuntimeException
- * @expectedExceptionMessage Request cannot be modified after it has been sent!
- */
public function testSetParameterAfterRequestSent()
{
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage('Request cannot be modified after it has been sent!');
+
$this->request = new AbstractRequestTest_MockAbstractRequest($this->getHttpClient(), $this->getHttpRequest());
$this->request->send();
@@ -418,11 +440,17 @@ public function testCanValidateExistingParameters()
$this->assertNull($this->request->validate('testMode', 'token'));
}
- /**
- * @expectedException \Omnipay\Common\Exception\InvalidRequestException
- */
+ public function testCanValidateAmountInteger()
+ {
+ $this->request->setAmountInteger(1);
+
+ $this->assertNull($this->request->validate('amount'));
+ }
+
public function testInvalidParametersThrowsException()
{
+ $this->expectException(\Omnipay\Common\Exception\InvalidRequestException::class);
+
$this->request->setTestMode(true);
$this->request->validate('testMode', 'token');
@@ -435,6 +463,7 @@ public function testNoCurrencyReturnedIfCurrencyNotSet()
public function testSend()
{
+ $this->request = m::mock('\Omnipay\Common\Message\AbstractRequest')->makePartial();
$response = m::mock('\Omnipay\Common\Message\ResponseInterface');
$data = array('request data');
@@ -444,12 +473,11 @@ public function testSend()
$this->assertSame($response, $this->request->send());
}
- /**
- * @expectedException \Omnipay\Common\Exception\RuntimeException
- * @expectedExceptionMessage You must call send() before accessing the Response!
- */
public function testGetResponseBeforeRequestSent()
{
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage('You must call send() before accessing the Response!');
+
$this->request = new AbstractRequestTest_MockAbstractRequest($this->getHttpClient(), $this->getHttpRequest());
$this->request->getResponse();
}
diff --git a/tests/Omnipay/Common/Message/AbstractResponseTest.php b/tests/Common/Message/AbstractResponseTest.php
similarity index 63%
rename from tests/Omnipay/Common/Message/AbstractResponseTest.php
rename to tests/Common/Message/AbstractResponseTest.php
index 1657073d..58b30656 100644
--- a/tests/Omnipay/Common/Message/AbstractResponseTest.php
+++ b/tests/Common/Message/AbstractResponseTest.php
@@ -7,7 +7,10 @@
class AbstractResponseTest extends TestCase
{
- public function setUp()
+ /** @var AbstractResponse */
+ protected $response;
+
+ public function setUp(): void
{
$this->response = m::mock('\Omnipay\Common\Message\AbstractResponse')->makePartial();
}
@@ -32,29 +35,56 @@ public function testDefaultMethods()
$this->assertNull($this->response->getTransactionReference());
$this->assertNull($this->response->getMessage());
$this->assertNull($this->response->getCode());
+ $this->assertNull($this->response->getRedirectUrl());
+ $this->assertEquals('GET', $this->response->getRedirectMethod());
+ $this->assertEquals([], $this->response->getRedirectData());
}
- /**
- * @expectedException \Omnipay\Common\Exception\RuntimeException
- * @expectedExceptionMessage This response does not support redirection.
- */
public function testGetRedirectResponseNotImplemented()
{
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage('This response does not support redirection.');
+
$this->response->getRedirectResponse();
}
- /**
- * @expectedException \Omnipay\Common\Exception\RuntimeException
- * @expectedExceptionMessage This response does not support redirection.
- */
public function testGetRedirectResponseNotSupported()
{
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage('This response does not support redirection.');
+
$this->response = m::mock('\Omnipay\Common\Message\AbstractResponseTest_MockRedirectResponse')->makePartial();
$this->response->shouldReceive('isRedirect')->once()->andReturn(false);
$this->response->getRedirectResponse();
}
+ public function testGetRedirectResponseUrlNotEmpty()
+ {
+ $this->expectException(\Omnipay\Common\Exception\RuntimeException::class);
+ $this->expectExceptionMessage('The given redirectUrl cannot be empty.');
+
+ $this->response = m::mock('\Omnipay\Common\Message\AbstractResponseTest_MockRedirectResponse')->makePartial();
+ $this->response->shouldReceive('getRedirectUrl')->once()->andReturn(null);
+
+ $this->response->getRedirectResponse();
+ }
+
+ /**
+ * @runInSeparateProcess
+ */
+ public function testRedirect()
+ {
+ $this->response = m::mock('\Omnipay\Common\Message\AbstractResponseTest_MockRedirectResponse')->makePartial();
+ $this->response->shouldReceive('getRedirectMethod')->andReturn('GET');
+
+ ob_start();
+ $this->response->redirect();
+ $body = ob_get_clean();
+
+ $this->assertStringContainsString('Redirecting to https://example.com/redirect?a=1&b=2', $body);
+ }
+
public function testGetRedirectResponseGet()
{
$this->response = m::mock('\Omnipay\Common\Message\AbstractResponseTest_MockRedirectResponse')->makePartial();
@@ -74,17 +104,17 @@ public function testGetRedirectResponsePost()
$httpResponse = $this->response->getRedirectResponse();
$this->assertSame(200, $httpResponse->getStatusCode());
- $this->assertContains('