new appraoch

This commit is contained in:
Tim Bendt
2025-11-26 13:22:58 -05:00
parent de3d100844
commit c520b7df89
6760 changed files with 1009780 additions and 0 deletions

View File

@@ -0,0 +1 @@
github: [barryvdh]

View File

@@ -0,0 +1,49 @@
name: "PHPUnit tests"
on:
pull_request:
push:
branches:
- "master"
jobs:
phpunit:
name: "PHPUnit tests"
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
dependencies:
- "lowest"
- "highest"
php-version:
- "7.2"
- "7.3"
- "7.4"
- "8.0"
operating-system:
- "ubuntu-latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- 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 --no-suggest"
- name: "Install highest dependencies"
if: ${{ matrix.dependencies == 'highest' }}
run: "composer update --no-interaction --no-progress --no-suggest"
- name: "Tests"
run: "vendor/bin/phpunit"

20
pancake/system/vendor/omnipay/common/LICENSE vendored Executable file
View File

@@ -0,0 +1,20 @@
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
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -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

View File

@@ -0,0 +1,74 @@
{
"name": "omnipay/common",
"type": "library",
"description": "Common components for Omnipay payment processing library",
"keywords": [
"gateway",
"merchant",
"omnipay",
"pay",
"payment",
"purchase"
],
"homepage": "https://github.com/thephpleague/omnipay-common",
"license": "MIT",
"authors": [
{
"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-4": { "Omnipay\\Common\\" : "src/Common" },
"classmap": ["src/Omnipay.php"]
},
"autoload-dev": {
"psr-4": { "Omnipay\\Common\\" : "tests/Common" },
"classmap": ["tests/OmnipayTest.php"]
},
"require": {
"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",
"moneyphp/money": "^3.1|^4.0.3"
},
"require-dev": {
"omnipay/tests": "^4.1",
"php-http/mock-client": "^1",
"php-http/guzzle7-adapter": "^1",
"squizlabs/php_codesniffer": "^3.5"
},
"extra": {
"branch-alias": {
"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
}

View File

@@ -0,0 +1,74 @@
<?php
namespace Omnipay\Common\Http;
use function GuzzleHttp\Psr7\str;
use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Message\RequestFactory;
use Omnipay\Common\Http\Exception\NetworkException;
use Omnipay\Common\Http\Exception\RequestException;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
class Client implements ClientInterface
{
/**
* The Http Client which implements `public function sendRequest(RequestInterface $request)`
* Note: Will be changed to PSR-18 when released
*
* @var HttpClient
*/
private $httpClient;
/**
* @var RequestFactory
*/
private $requestFactory;
public function __construct($httpClient = null, RequestFactory $requestFactory = null)
{
$this->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);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Omnipay\Common\Http;
use Omnipay\Common\Http\Exception\NetworkException;
use Omnipay\Common\Http\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
interface ClientInterface
{
/**
* Creates a new PSR-7 request.
*
* @param string $method
* @param string|UriInterface $uri
* @param array $headers
* @param resource|string|StreamInterface|null $body
* @param string $protocolVersion
*
* @throws RequestException when the HTTP client is passed a request that is invalid and cannot be sent.
* @throws NetworkException if there is an error with the network or the remote server cannot be reached.
*
* @return ResponseInterface
*/
public function request(
$method,
$uri,
array $headers = [],
$body = null,
$protocolVersion = '1.1'
);
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Omnipay\Common\Http;
use Psr\Http\Message\RequestInterface;
use Throwable;
abstract class Exception extends \RuntimeException
{
/** @var RequestInterface */
protected $request;
public function __construct($message, RequestInterface $request, $previous = null)
{
$this->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;
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Omnipay\Common\Http\Exception;
use Omnipay\Common\Http\Exception;
class NetworkException extends Exception
{
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Omnipay\Common\Http\Exception;
use Omnipay\Common\Http\Exception;
class RequestException extends Exception
{
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Omnipay\Common;
use Omnipay\Common\Exception\InvalidRequestException;
use Symfony\Component\HttpFoundation\ParameterBag;
trait ParametersTrait
{
/**
* Internal storage of all of the parameters.
*
* @var ParameterBag
*/
protected $parameters;
/**
* Set one parameter.
*
* @param string $key Parameter key
* @param mixed $value Parameter value
* @return $this
*/
protected function setParameter($key, $value)
{
$this->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");
}
}
}
}

View File

@@ -0,0 +1,351 @@
<?php
/**
* Base payment gateway class
*/
namespace Omnipay\Common;
use Guzzle\Http\ClientInterface;
use Guzzle\Http\Client as HttpClient;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
/**
* Base payment gateway class
*
* 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
* and methods that all gateways should have.
*
* Example:
*
* <code>
* // Initialise the gateway
* $gateway->initialize(...);
*
* // Get the gateway parameters.
* $parameters = $gateway->getParameters();
*
* // Create a credit card object
* $card = new CreditCard(...);
*
* // Do an authorisation transaction on the gateway
* if ($gateway->supportsAuthorize()) {
* $gateway->authorize(...);
* } else {
* throw new \Exception('Gateway does not support authorize()');
* }
* </code>
*
* 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;
/**
* @var \Guzzle\Http\ClientInterface
*/
protected $httpClient;
/**
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $httpRequest;
/**
* Create a new gateway instance
*
* @param ClientInterface $httpClient A Guzzle client to make API calls with
* @param HttpRequest $httpRequest A Symfony HTTP request object
*/
public function __construct(ClientInterface $httpClient = null, HttpRequest $httpRequest = null)
{
$this->httpClient = $httpClient ?: $this->getDefaultHttpClient();
$this->httpRequest = $httpRequest ?: $this->getDefaultHttpRequest();
$this->initialize();
}
/**
* Get the short name of the Gateway
*
* @return string
*/
public function getShortName()
{
return Helper::getGatewayShortName(get_class($this));
}
/**
* Initialize this gateway with default parameters
*
* @param array $parameters
* @return $this
*/
public function initialize(array $parameters = array())
{
$this->parameters = new ParameterBag;
// set default parameters
foreach ($this->getDefaultParameters() as $key => $value) {
if (is_array($value)) {
$this->parameters->set($key, reset($value));
} else {
$this->parameters->set($key, $value);
}
}
Helper::initialize($this, $parameters);
return $this;
}
/**
* @return array
*/
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);
}
/**
* @param string $key
* @param mixed $value
* @return $this
*/
public function setParameter($key, $value)
{
$this->parameters->set($key, $value);
return $this;
}
/**
* @return boolean
*/
public function getTestMode()
{
return $this->getParameter('testMode');
}
/**
* @param boolean $value
* @return $this
*/
public function setTestMode($value)
{
return $this->setParameter('testMode', $value);
}
/**
* @return string
*/
public function getCurrency()
{
return strtoupper($this->getParameter('currency'));
}
/**
* @param string $value
* @return $this
*/
public function setCurrency($value)
{
return $this->setParameter('currency', $value);
}
/**
* Supports Authorize
*
* @return boolean True if this gateway supports the authorize() method
*/
public function supportsAuthorize()
{
return method_exists($this, 'authorize');
}
/**
* Supports Complete Authorize
*
* @return boolean True if this gateway supports the completeAuthorize() method
*/
public function supportsCompleteAuthorize()
{
return method_exists($this, 'completeAuthorize');
}
/**
* Supports Capture
*
* @return boolean True if this gateway supports the capture() method
*/
public function supportsCapture()
{
return method_exists($this, 'capture');
}
/**
* Supports Purchase
*
* @return boolean True if this gateway supports the purchase() method
*/
public function supportsPurchase()
{
return method_exists($this, 'purchase');
}
/**
* Supports Complete Purchase
*
* @return boolean True if this gateway supports the completePurchase() method
*/
public function supportsCompletePurchase()
{
return method_exists($this, 'completePurchase');
}
/**
* Supports Refund
*
* @return boolean True if this gateway supports the refund() method
*/
public function supportsRefund()
{
return method_exists($this, 'refund');
}
/**
* Supports Void
*
* @return boolean True if this gateway supports the void() method
*/
public function supportsVoid()
{
return method_exists($this, 'void');
}
/**
* Supports AcceptNotification
*
* @return boolean True if this gateway supports the acceptNotification() method
*/
public function supportsAcceptNotification()
{
return method_exists($this, 'acceptNotification');
}
/**
* Supports CreateCard
*
* @return boolean True if this gateway supports the create() method
*/
public function supportsCreateCard()
{
return method_exists($this, 'createCard');
}
/**
* Supports DeleteCard
*
* @return boolean True if this gateway supports the delete() method
*/
public function supportsDeleteCard()
{
return method_exists($this, 'deleteCard');
}
/**
* Supports UpdateCard
*
* @return boolean True if this gateway supports the update() method
*/
public function supportsUpdateCard()
{
return method_exists($this, 'updateCard');
}
/**
* Create and initialize a request object
*
* This function is usually used to create objects of type
* Omnipay\Common\Message\AbstractRequest (or a non-abstract subclass of it)
* and initialise them with using existing parameters from this gateway.
*
* Example:
*
* <code>
* class MyRequest extends \Omnipay\Common\Message\AbstractRequest {};
*
* class MyGateway extends \Omnipay\Common\AbstractGateway {
* function myRequest($parameters) {
* $this->createRequest('MyRequest', $parameters);
* }
* }
*
* // Create the gateway object
* $gw = Omnipay::create('MyGateway');
*
* // Create the request object
* $myRequest = $gw->myRequest($someParameters);
* </code>
*
* @see \Omnipay\Common\Message\AbstractRequest
* @param string $class The request class name
* @param array $parameters
* @return \Omnipay\Common\Message\AbstractRequest
*/
protected function createRequest($class, array $parameters)
{
$obj = new $class($this->httpClient, $this->httpRequest);
return $obj->initialize(array_replace($this->getParameters(), $parameters));
}
/**
* Get the global default HTTP client.
*
* @return HttpClient
*/
protected function getDefaultHttpClient()
{
return new HttpClient(
'',
array(
'curl.options' => array(CURLOPT_CONNECTTIMEOUT => 60),
)
);
}
/**
* Get the global default HTTP request.
*
* @return HttpRequest
*/
protected function getDefaultHttpRequest()
{
return HttpRequest::createFromGlobals();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
<?php
namespace Omnipay\Common\Exception;
/**
* Bad Method Call Exception
*/
class BadMethodCallException extends \BadMethodCallException implements OmnipayException
{
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Omnipay\Common\Exception;
/**
* Invalid Credit Card Exception
*
* Thrown when a credit card is invalid or missing required fields.
*/
class InvalidCreditCardException extends \Exception implements OmnipayException
{
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Omnipay\Common\Exception;
/**
* Invalid Request Exception
*
* Thrown when a request is invalid or missing required fields.
*/
class InvalidRequestException extends \Exception implements OmnipayException
{
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Omnipay\Common\Exception;
/**
* Invalid Response exception.
*
* Thrown when a gateway responded with invalid or unexpected data (for example, a security hash did not match).
*/
class InvalidResponseException extends \Exception implements OmnipayException
{
public function __construct($message = "Invalid response from payment gateway", $code = 0, $previous = null)
{
parent::__construct($message, $code, $previous);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Omnipay\Common\Exception;
/**
* Omnipay Exception marker interface
*/
interface OmnipayException
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Omnipay\Common\Exception;
/**
* Runtime Exception
*/
class RuntimeException extends \RuntimeException implements OmnipayException
{
}

View File

@@ -0,0 +1,122 @@
<?php
/**
* Omnipay Gateway Factory class
*/
namespace Omnipay\Common;
use Guzzle\Http\ClientInterface;
use Omnipay\Common\Exception\RuntimeException;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
/**
* Omnipay Gateway Factory class
*
* This class abstracts a set of gateways that can be independently
* registered, accessed, and used.
*
* Note that static calls to the Omnipay class are routed to this class by
* the static call router (__callStatic) in Omnipay.
*
* Example:
*
* <code>
* // Create a gateway for the PayPal ExpressGateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('ExpressGateway');
* </code>
*
* @see Omnipay\Omnipay
*/
class GatewayFactory
{
/**
* Internal storage for all available gateways
*
* @var array
*/
private $gateways = array();
/**
* All available gateways
*
* @return array An array of gateway names
*/
public function all()
{
return $this->gateways;
}
/**
* Replace the list of available gateways
*
* @param array $gateways An array of gateway names
*/
public function replace(array $gateways)
{
$this->gateways = $gateways;
}
/**
* Register a new gateway
*
* @param string $className Gateway name
*/
public function register($className)
{
if (!in_array($className, $this->gateways)) {
$this->gateways[] = $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 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)
{
$class = Helper::getGatewayClassName($class);
if (!class_exists($class)) {
throw new RuntimeException("Class '$class' not found");
}
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'];
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* Payment gateway interface
*/
namespace Omnipay\Common;
/**
* Payment gateway interface
*
* 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)
* Authorize an amount on the customers card
* @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)
* Capture an amount you have previously authorized
* @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)
* Handle return from off-site gateways after purchase
* @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)
* Generally can only be called up to 24 hours after submitting a transaction
* @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)
* Update a stored card
* @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.
*/
public function getName();
/**
* Get gateway short name
*
* This name can be used with GatewayFactory as an alias of the gateway class,
* to create new instances of this gateway.
*/
public function getShortName();
/**
* Define gateway parameters, in the following format:
*
* array(
* 'username' => '', // string variable
* 'testMode' => false, // boolean variable
* 'landingPage' => array('billing', 'login'), // enum variable, first item is default
* );
*/
public function getDefaultParameters();
/**
* Initialize gateway with parameters
*/
public function initialize(array $parameters = array());
/**
* Get all gateway parameters
*
* @return array
*/
public function getParameters();
}

View File

@@ -0,0 +1,167 @@
<?php
/**
* Helper class
*/
namespace Omnipay\Common;
use InvalidArgumentException;
/**
* Helper class
*
* This class defines various static utility functions that are in use
* throughout the Omnipay system.
*/
class Helper
{
/**
* Convert a string to camelCase. Strings already in camelCase will not be harmed.
*
* @param string $str The input string
* @return string camelCased output string
*/
public static function camelCase($str)
{
$str = self::convertToLowercase($str);
return preg_replace_callback(
'/_([a-z])/',
function ($match) {
return strtoupper($match[1]);
},
$str
);
}
/**
* Convert strings with underscores to be all lowercase before camelCase is preformed.
*
* @param string $str The input string
* @return string The output string
*/
protected static function convertToLowercase($str)
{
$explodedStr = explode('_', $str);
if (count($explodedStr) > 1) {
foreach ($explodedStr as $value) {
$lowercasedStr[] = strtolower($value);
}
$str = implode('_', $lowercasedStr);
}
return $str;
}
/**
* Validate a card number according to the Luhn algorithm.
*
* @param string $number The card number to validate
* @return boolean True if the supplied card number is valid
*/
public static function validateLuhn($number)
{
$str = '';
foreach (array_reverse(str_split($number)) as $i => $c) {
$str .= $i % 2 ? $c * 2 : $c;
}
return array_sum(str_split($str)) % 10 === 0;
}
/**
* Initialize an object with a given array of parameters
*
* Parameters are automatically converted to camelCase. Any parameters which do
* not match a setter on the target object are ignored.
*
* @param mixed $target The object to set parameters on
* @param array $parameters An array of parameters to set
*/
public static function initialize($target, $parameters)
{
if (is_array($parameters)) {
foreach ($parameters as $key => $value) {
$method = 'set'.ucfirst(static::camelCase($key));
if (method_exists($target, $method)) {
$target->$method($value);
}
}
}
}
/**
* Resolve a gateway class to a short name.
*
* The short name can be used with GatewayFactory as an alias of the gateway class,
* to create new instances of a gateway.
*/
public static function getGatewayShortName($className)
{
if (0 === strpos($className, '\\')) {
$className = substr($className, 1);
}
if (0 === strpos($className, 'Omnipay\\')) {
return trim(str_replace('\\', '_', substr($className, 8, -7)), '_');
}
return '\\'.$className;
}
/**
* Resolve a short gateway name to a full namespaced gateway class.
*
* Class names beginning with a namespace marker (\) are left intact.
* Non-namespaced classes are expected to be in the \Omnipay namespace, e.g.:
*
* \Custom\Gateway => \Custom\Gateway
* \Custom_Gateway => \Custom_Gateway
* Stripe => \Omnipay\Stripe\Gateway
* PayPal\Express => \Omnipay\PayPal\ExpressGateway
* PayPal_Express => \Omnipay\PayPal\ExpressGateway
*
* @param string $shortName The short gateway name
* @return string The fully namespaced gateway class name
*/
public static function getGatewayClassName($shortName)
{
if (0 === strpos($shortName, '\\')) {
return $shortName;
}
// replace underscores with namespace marker, PSR-0 style
$shortName = str_replace('_', '\\', $shortName);
if (false === strpos($shortName, '\\')) {
$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;
}
}

View File

@@ -0,0 +1,86 @@
<?php
/**
* Issuer
*/
namespace Omnipay\Common;
/**
* Issuer
*
* This class abstracts some functionality around card issuers used in the
* Omnipay system.
*/
class Issuer
{
/**
* The identifier of the issuer.
*
* @var string
*/
protected $id;
/**
* The full name of the issuer.
*
* @var string
*/
protected $name;
/**
* The ID of a payment method that the issuer belongs to.
*
* @see PaymentMethod
*
* @var string
*/
protected $paymentMethod;
/**
* Create a new Issuer
*
* @see PaymentMethod
*
* @param string $id The identifier of this issuer
* @param string $name The name of this issuer
* @param string|null $paymentMethod The ID of a payment method this issuer belongs to
*/
public function __construct($id, $name, $paymentMethod = null)
{
$this->id = $id;
$this->name = $name;
$this->paymentMethod = $paymentMethod;
}
/**
* The identifier of this issuer
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* The name of this issuer
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* The ID of a payment method this issuer belongs to
*
* @see PaymentMethod
*
* @return string
*/
public function getPaymentMethod()
{
return $this->paymentMethod;
}
}

View File

@@ -0,0 +1,129 @@
<?php
/**
* Cart Item
*/
namespace Omnipay\Common;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
* Cart Item
*
* This class defines a single cart item in the Omnipay system.
*
* @see ItemInterface
*/
class Item implements ItemInterface
{
/**
* @var \Symfony\Component\HttpFoundation\ParameterBag
*/
protected $parameters;
/**
* Create a new item with the specified parameters
*
* @param array|null $parameters An array of parameters to set on the new object
*/
public function __construct($parameters = null)
{
$this->initialize($parameters);
}
/**
* Initialize this item with the specified parameters
*
* @param array|null $parameters An array of parameters to set on this object
* @return $this Item
*/
public function initialize($parameters = null)
{
$this->parameters = new ParameterBag;
Helper::initialize($this, $parameters);
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}
*/
public function getName()
{
return $this->getParameter('name');
}
/**
* Set the item name
*/
public function setName($value)
{
return $this->setParameter('name', $value);
}
/**
* {@inheritDoc}
*/
public function getDescription()
{
return $this->getParameter('description');
}
/**
* Set the item description
*/
public function setDescription($value)
{
return $this->setParameter('description', $value);
}
/**
* {@inheritDoc}
*/
public function getQuantity()
{
return $this->getParameter('quantity');
}
/**
* Set the item quantity
*/
public function setQuantity($value)
{
return $this->setParameter('quantity', $value);
}
/**
* {@inheritDoc}
*/
public function getPrice()
{
return $this->getParameter('price');
}
/**
* Set the item price
*/
public function setPrice($value)
{
return $this->setParameter('price', $value);
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* Cart Item Bag
*/
namespace Omnipay\Common;
/**
* Cart Item Bag
*
* 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
*/
protected $items;
/**
* Constructor
*
* @param array $items An array of items
*/
public function __construct(array $items = array())
{
$this->replace($items);
}
/**
* Return all the items
*
* @see Item
*
* @return array An array of items
*/
public function all()
{
return $this->items;
}
/**
* Replace the contents of this bag with the specified items
*
* @see Item
*
* @param array $items An array of items
*/
public function replace(array $items = array())
{
$this->items = array();
foreach ($items as $item) {
$this->add($item);
}
}
/**
* Add an item to the bag
*
* @see Item
*
* @param ItemInterface|array $item An existing item, or associative array of item parameters
*/
public function add($item)
{
if ($item instanceof ItemInterface) {
$this->items[] = $item;
} else {
$this->items[] = new Item($item);
}
}
/**
* Returns an iterator for items
*
* @return \ArrayIterator An \ArrayIterator instance
*/
public function getIterator()
{
return new \ArrayIterator($this->items);
}
/**
* Returns the number of items
*
* @return int The number of items
*/
public function count()
{
return count($this->items);
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Cart Item interface
*/
namespace Omnipay\Common;
/**
* Cart Item interface
*
* This interface defines the functionality that all cart items in
* the Omnipay system are to have.
*/
interface ItemInterface
{
/**
* Name of the item
*/
public function getName();
/**
* Description of the item
*/
public function getDescription();
/**
* Quantity of the item
*/
public function getQuantity();
/**
* Price of the item
*/
public function getPrice();
}

View File

@@ -0,0 +1,694 @@
<?php
/**
* Abstract Request
*/
namespace Omnipay\Common\Message;
use Guzzle\Http\ClientInterface;
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\ItemBag;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request as HttpRequest;
use InvalidArgumentException;
/**
* Abstract Request
*
* This abstract class implements RequestInterface and defines a basic
* set of functions that all Omnipay Requests are intended to include.
*
* Requests of this class are usually created using the createRequest
* function of the gateway and then actioned using methods within this
* class or a class that extends this class.
*
* Example -- creating a request:
*
* <code>
* class MyRequest extends \Omnipay\Common\Message\AbstractRequest {};
*
* class MyGateway extends \Omnipay\Common\AbstractGateway {
* function myRequest($parameters) {
* $this->createRequest('MyRequest', $parameters);
* }
* }
*
* // Create the gateway object
* $gw = Omnipay::create('MyGateway');
*
* // Create the request object
* $myRequest = $gw->myRequest($someParameters);
* </code>
*
* Example -- validating and sending a request:
*
* <code>
* try {
* $myRequest->validate();
* $myResponse = $myRequest->send();
* } catch (InvalidRequestException $e) {
* print "Something went wrong: " . $e->getMessage() . "\n";
* }
* // now do something with the $myResponse object, test for success, etc.
* </code>
*
* @see RequestInterface
* @see AbstractResponse
*/
abstract class AbstractRequest implements RequestInterface
{
/**
* The request parameters
*
* @var \Symfony\Component\HttpFoundation\ParameterBag
*/
protected $parameters;
/**
* The request client.
*
* @var \Guzzle\Http\ClientInterface
*/
protected $httpClient;
/**
* The HTTP request object.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $httpRequest;
/**
* An associated ResponseInterface.
*
* @var ResponseInterface
*/
protected $response;
/**
* @var bool
*/
protected $zeroAmountAllowed = true;
/**
* @var bool
*/
protected $negativeAmountAllowed = false;
/**
* Create a new Request
*
* @param ClientInterface $httpClient A Guzzle client to make API calls with
* @param HttpRequest $httpRequest A Symfony HTTP request object
*/
public function __construct(ClientInterface $httpClient, HttpRequest $httpRequest)
{
$this->httpClient = $httpClient;
$this->httpRequest = $httpRequest;
$this->initialize();
}
/**
* Initialize the object with parameters.
*
* If any unknown parameters passed, they will be ignored.
*
* @param array $parameters An associative array of parameters
*
* @return $this
* @throws RuntimeException
*/
public function initialize(array $parameters = array())
{
if (null !== $this->response) {
throw new RuntimeException('Request cannot be modified after it has been sent!');
}
$this->parameters = new ParameterBag;
Helper::initialize($this, $parameters);
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
* @throws RuntimeException if a request parameter is modified after the request has been sent.
*/
protected function setParameter($key, $value)
{
if (null !== $this->response) {
throw new RuntimeException('Request cannot be modified after it has been sent!');
}
$this->parameters->set($key, $value);
return $this;
}
/**
* Gets the test mode of the request from the gateway.
*
* @return boolean
*/
public function getTestMode()
{
return $this->getParameter('testMode');
}
/**
* Sets the test mode of the request.
*
* @param boolean $value True for test mode on.
* @return AbstractRequest
*/
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.
*
* @return CreditCard
*/
public function getCard()
{
return $this->getParameter('card');
}
/**
* Sets the card.
*
* @param CreditCard $value
* @return AbstractRequest Provides a fluent interface
*/
public function setCard($value)
{
if ($value && !$value instanceof CreditCard) {
$value = new CreditCard($value);
}
return $this->setParameter('card', $value);
}
/**
* Get the card token.
*
* @return string
*/
public function getToken()
{
return $this->getParameter('token');
}
/**
* Sets the card token.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setToken($value)
{
return $this->setParameter('token', $value);
}
/**
* Get the card reference.
*
* @return string
*/
public function getCardReference()
{
return $this->getParameter('cardReference');
}
/**
* Sets the card reference.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setCardReference($value)
{
return $this->setParameter('cardReference', $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.
*/
public function toFloat($value)
{
try {
return Helper::toFloat($value);
} catch (InvalidArgumentException $e) {
// Throw old exception for legacy implementations.
throw new InvalidRequestException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* 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.
*/
public function getAmount()
{
$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).'
);
};
}
$amount = $this->toFloat($amount);
// Check for a negative amount.
if (!$this->negativeAmountAllowed && $amount < 0) {
throw new InvalidRequestException('A negative amount is not allowed.');
}
// Check for a zero amount.
if (!$this->zeroAmountAllowed && $amount === 0.0) {
throw new InvalidRequestException('A zero amount is not allowed.');
}
// 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()) {
throw new InvalidRequestException('Amount precision is too high for currency.');
}
return $this->formatCurrency($amount);
}
}
/**
* Sets the payment amount.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setAmount($value)
{
return $this->setParameter('amount', $value);
}
/**
* Get the payment amount as an integer.
*
* @return integer
*/
public function getAmountInteger()
{
return (int) round($this->getAmount() * $this->getCurrencyDecimalFactor());
}
/**
* Get the payment currency code.
*
* @return string
*/
public function getCurrency()
{
return $this->getParameter('currency');
}
/**
* Sets the payment currency code.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setCurrency($value)
{
if ($value !== null) {
$value = strtoupper($value);
}
return $this->setParameter('currency', $value);
}
/**
* Get the payment currency number.
*
* @return integer
*/
public function getCurrencyNumeric()
{
if ($currency = Currency::find($this->getCurrency())) {
return $currency->getNumeric();
}
}
/**
* Get the number of decimal places in the payment currency.
*
* @return integer
*/
public function getCurrencyDecimalPlaces()
{
if ($currency = Currency::find($this->getCurrency())) {
return $currency->getDecimals();
}
return 2;
}
private function getCurrencyDecimalFactor()
{
return pow(10, $this->getCurrencyDecimalPlaces());
}
/**
* Format an amount for the payment currency.
*
* @return string
*/
public function formatCurrency($amount)
{
return number_format(
$amount,
$this->getCurrencyDecimalPlaces(),
'.',
''
);
}
/**
* Get the request description.
*
* @return string
*/
public function getDescription()
{
return $this->getParameter('description');
}
/**
* Sets the request description.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setDescription($value)
{
return $this->setParameter('description', $value);
}
/**
* Get the transaction ID.
*
* The transaction ID is the identifier generated by the merchant website.
*
* @return string
*/
public function getTransactionId()
{
return $this->getParameter('transactionId');
}
/**
* Sets the transaction ID.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setTransactionId($value)
{
return $this->setParameter('transactionId', $value);
}
/**
* Get the transaction reference.
*
* The transaction reference is the identifier generated by the remote
* payment gateway.
*
* @return string
*/
public function getTransactionReference()
{
return $this->getParameter('transactionReference');
}
/**
* Sets the transaction reference.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setTransactionReference($value)
{
return $this->setParameter('transactionReference', $value);
}
/**
* A list of items in this order
*
* @return ItemBag|null A bag containing items in this order
*/
public function getItems()
{
return $this->getParameter('items');
}
/**
* Set the items in this order
*
* @param ItemBag|array $items An array of items in this order
* @return AbstractRequest
*/
public function setItems($items)
{
if ($items && !$items instanceof ItemBag) {
$items = new ItemBag($items);
}
return $this->setParameter('items', $items);
}
/**
* Get the client IP address.
*
* @return string
*/
public function getClientIp()
{
return $this->getParameter('clientIp');
}
/**
* Sets the client IP address.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setClientIp($value)
{
return $this->setParameter('clientIp', $value);
}
/**
* Get the request return URL.
*
* @return string
*/
public function getReturnUrl()
{
return $this->getParameter('returnUrl');
}
/**
* Sets the request return URL.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setReturnUrl($value)
{
return $this->setParameter('returnUrl', $value);
}
/**
* Get the request cancel URL.
*
* @return string
*/
public function getCancelUrl()
{
return $this->getParameter('cancelUrl');
}
/**
* Sets the request cancel URL.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setCancelUrl($value)
{
return $this->setParameter('cancelUrl', $value);
}
/**
* Get the request notify URL.
*
* @return string
*/
public function getNotifyUrl()
{
return $this->getParameter('notifyUrl');
}
/**
* Sets the request notify URL.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setNotifyUrl($value)
{
return $this->setParameter('notifyUrl', $value);
}
/**
* Get the payment issuer.
*
* This field is used by some European gateways, and normally represents
* the bank where an account is held (separate from the card brand).
*
* @return string
*/
public function getIssuer()
{
return $this->getParameter('issuer');
}
/**
* Set the payment issuer.
*
* This field is used by some European gateways, and normally represents
* the bank where an account is held (separate from the card brand).
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setIssuer($value)
{
return $this->setParameter('issuer', $value);
}
/**
* Get the payment issuer.
*
* This field is used by some European gateways, which support
* multiple payment providers with a single API.
*
* @return string
*/
public function getPaymentMethod()
{
return $this->getParameter('paymentMethod');
}
/**
* Set the payment method.
*
* This field is used by some European gateways, which support
* multiple payment providers with a single API.
*
* @param string $value
* @return AbstractRequest Provides a fluent interface
*/
public function setPaymentMethod($value)
{
return $this->setParameter('paymentMethod', $value);
}
/**
* Send the request
*
* @return ResponseInterface
*/
public function send()
{
$data = $this->getData();
return $this->sendData($data);
}
/**
* Get the associated Response.
*
* @return ResponseInterface
*/
public function getResponse()
{
if (null === $this->response) {
throw new RuntimeException('You must call send() before accessing the Response!');
}
return $this->response;
}
}

View File

@@ -0,0 +1,224 @@
<?php
/**
* Abstract Response
*/
namespace Omnipay\Common\Message;
use Omnipay\Common\Exception\RuntimeException;
use Symfony\Component\HttpFoundation\RedirectResponse as HttpRedirectResponse;
use Symfony\Component\HttpFoundation\Response as HttpResponse;
/**
* Abstract Response
*
* This abstract class implements ResponseInterface and defines a basic
* set of functions that all Omnipay Requests are intended to include.
*
* Objects of this class or a subclass are usually created in the Request
* object (subclass of AbstractRequest) as the return parameters from the
* send() function.
*
* Example -- validating and sending a request:
*
* <code>
* $myResponse = $myRequest->send();
* // now do something with the $myResponse object, test for success, etc.
* </code>
*
* @see ResponseInterface
*/
abstract class AbstractResponse implements ResponseInterface
{
/**
* The embodied request object.
*
* @var RequestInterface
*/
protected $request;
/**
* The data contained in the response.
*
* @var mixed
*/
protected $data;
/**
* Constructor
*
* @param RequestInterface $request the initiating request.
* @param mixed $data
*/
public function __construct(RequestInterface $request, $data)
{
$this->request = $request;
$this->data = $data;
}
/**
* Get the initiating request object.
*
* @return RequestInterface
*/
public function getRequest()
{
return $this->request;
}
/**
* Is the response successful?
*
* @return boolean
*/
public function isPending()
{
return false;
}
/**
* Does the response require a redirect?
*
* @return boolean
*/
public function isRedirect()
{
return false;
}
/**
* Is the response a transparent redirect?
*
* @return boolean
*/
public function isTransparentRedirect()
{
return false;
}
/**
* Is the transaction cancelled by the user?
*
* @return boolean
*/
public function isCancelled()
{
return false;
}
/**
* Get the response data.
*
* @return mixed
*/
public function getData()
{
return $this->data;
}
/**
* Response Message
*
* @return null|string A response message from the payment gateway
*/
public function getMessage()
{
return null;
}
/**
* Response code
*
* @return null|string A response code from the payment gateway
*/
public function getCode()
{
return null;
}
/**
* Gateway Reference
*
* @return null|string A reference provided by the gateway to represent this transaction
*/
public function getTransactionReference()
{
return null;
}
/**
* Get the transaction ID as generated by the merchant website.
*
* @return string
*/
public function getTransactionId()
{
return null;
}
/**
* 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
*/
public function getRedirectResponse()
{
if (!$this instanceof RedirectResponseInterface || !$this->isRedirect()) {
throw new RuntimeException('This response does not support redirection.');
}
if ('GET' === $this->getRedirectMethod()) {
return HttpRedirectResponse::create($this->getRedirectUrl());
} elseif ('POST' === $this->getRedirectMethod()) {
$hiddenFields = '';
foreach ($this->getRedirectData() as $key => $value) {
$hiddenFields .= sprintf(
'<input type="hidden" name="%1$s" value="%2$s" />',
htmlentities($key, ENT_QUOTES, 'UTF-8', false),
htmlentities($value, ENT_QUOTES, 'UTF-8', false)
)."\n";
}
$output = '<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Redirecting...</title>
</head>
<body onload="document.forms[0].submit();">
<form action="%1$s" method="post">
<p>Redirecting to payment page...</p>
<p>
%2$s
<input type="submit" value="Continue" />
</p>
</form>
</body>
</html>';
$output = sprintf(
$output,
htmlentities($this->getRedirectUrl(), ENT_QUOTES, 'UTF-8', false),
$hiddenFields
);
return HttpResponse::create($output);
}
throw new RuntimeException('Invalid redirect method "'.$this->getRedirectMethod().'".');
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* Fetch Issuers Response interface
*/
namespace Omnipay\Common\Message;
/**
* Fetch Issuers Response interface
*
* This interface class defines the functionality of a response
* that is a "fetch issuers" response. It extends the ResponseInterface
* interface class with some extra functions relating to the
* specifics of a response to fetch the issuers from the gateway.
* This happens when the gateway needs the customer to choose a
* card issuer.
*
* @see ResponseInterface
* @see Omnipay\Common\Issuer
*/
interface FetchIssuersResponseInterface extends ResponseInterface
{
/**
* Get the returned list of issuers.
*
* These represent banks which the user must choose between.
*
* @return \Omnipay\Common\Issuer[]
*/
public function getIssuers();
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* Fetch Payment Methods Response interface
*/
namespace Omnipay\Common\Message;
/**
* Fetch Payment Methods Response interface
*
* This interface class defines the functionality of a response
* that is a "fetch payment method" response. It extends the ResponseInterface
* interface class with some extra functions relating to the
* specifics of a response to fetch the payment method from the gateway.
* This happens when the gateway needs the customer to choose a
* payment method.
*
* @see ResponseInterface
* @see Omnipay\Common\PaymentMethod
*/
interface FetchPaymentMethodsResponseInterface extends ResponseInterface
{
/**
* Get the returned list of payment methods.
*
* These represent separate payment methods which the user must choose between.
*
* @return \Omnipay\Common\PaymentMethod[]
*/
public function getPaymentMethods();
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* Message Interface
*/
namespace Omnipay\Common\Message;
/**
* Message Interface
*
* This interface class defines the standard functions that any Omnipay message
* interface needs to be able to provide.
*/
interface MessageInterface
{
/**
* Get the raw data array for this message. The format of this varies from gateway to
* gateway, but will usually be either an associative array, or a SimpleXMLElement.
*
* @return mixed
*/
public function getData();
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Omnipay\Common\Message;
/**
* Incoming notification
*/
interface NotificationInterface extends MessageInterface
{
const STATUS_COMPLETED = 'completed';
const STATUS_PENDING = 'pending';
const STATUS_FAILED = 'failed';
/**
* Gateway Reference
*
* @return string A reference provided by the gateway to represent this transaction
*/
public function getTransactionReference();
/**
* Was the transaction successful?
*
* @return string Transaction status, one of {@see STATUS_COMPLETED}, {@see #STATUS_PENDING},
* or {@see #STATUS_FAILED}.
*/
public function getTransactionStatus();
/**
* Response Message
*
* @return string A response message from the payment gateway
*/
public function getMessage();
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* Redirect Response interface
*/
namespace Omnipay\Common\Message;
/**
* Redirect Response interface
*
* This interface class defines the functionality of a response
* that is a redirect response. It extends the ResponseInterface
* interface class with some extra functions relating to the
* specifics of a redirect response from the gateway.
*
* @see ResponseInterface
*/
interface RedirectResponseInterface extends ResponseInterface
{
/**
* Gets the redirect target url.
*
* @return string
*/
public function getRedirectUrl();
/**
* Get the required redirect method (either GET or POST).
*
* @return string
*/
public function getRedirectMethod();
/**
* Gets the redirect form data array, if the redirect method is POST.
*
* @return array
*/
public function getRedirectData();
/**
* Perform the required redirect.
*
* @return void
*/
public function redirect();
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* Request Interface
*/
namespace Omnipay\Common\Message;
/**
* Request Interface
*
* 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
{
/**
* Initialize request with parameters
* @param array $parameters The parameters to send
*/
public function initialize(array $parameters = array());
/**
* Get all request parameters
*
* @return array
*/
public function getParameters();
/**
* Get the response to this request (if the request has been sent)
*
* @return ResponseInterface
*/
public function getResponse();
/**
* Send the request
*
* @return ResponseInterface
*/
public function send();
/**
* Send the request with specified data
*
* @param mixed $data The data to send
* @return ResponseInterface
*/
public function sendData($data);
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* Response interface
*/
namespace Omnipay\Common\Message;
/**
* Response Interface
*
* 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
{
/**
* Get the original request which generated this response
*
* @return RequestInterface
*/
public function getRequest();
/**
* Is the response successful?
*
* @return boolean
*/
public function isSuccessful();
/**
* Does the response require a redirect?
*
* @return boolean
*/
public function isRedirect();
/**
* Is the transaction cancelled by the user?
*
* @return boolean
*/
public function isCancelled();
/**
* Response Message
*
* @return null|string A response message from the payment gateway
*/
public function getMessage();
/**
* Response code
*
* @return null|string A response code from the payment gateway
*/
public function getCode();
/**
* Gateway Reference
*
* @return null|string A reference provided by the gateway to represent this transaction
*/
public function getTransactionReference();
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* Payment Method
*/
namespace Omnipay\Common;
/**
* Payment Method
*
* This class defines a payment method to be used in the Omnipay system.
*
* @see Issuer
*/
class PaymentMethod
{
/**
* The ID of the payment method. Used as the payment method ID in the
* Issuer class.
*
* @see Issuer
*
* @var string
*/
protected $id;
/**
* The full name of the payment method
*
* @var string
*/
protected $name;
/**
* Create a new PaymentMethod
*
* @param string $id The identifier of this payment method
* @param string $name The name of this payment method
*/
public function __construct($id, $name)
{
$this->id = $id;
$this->name = $name;
}
/**
* The identifier of this payment method
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* The name of this payment method
*
* @return string
*/
public function getName()
{
return $this->name;
}
}

View File

@@ -0,0 +1,117 @@
<?php
/**
* Omnipay class
*/
namespace Omnipay;
use Omnipay\Common\GatewayFactory;
/**
* Omnipay class
*
* Provides static access to the gateway factory methods. This is the
* recommended route for creation and establishment of payment gateway
* objects via the standard GatewayFactory.
*
* Example:
*
* <code>
* // Create a gateway for the PayPal ExpressGateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('ExpressGateway');
*
* // Initialise the gateway
* $gateway->initialize(...);
*
* // Get the gateway parameters.
* $parameters = $gateway->getParameters();
*
* // Create a credit card object
* $card = new CreditCard(...);
*
* // Do an authorisation transaction on the gateway
* if ($gateway->supportsAuthorize()) {
* $gateway->authorize(...);
* } else {
* throw new \Exception('Gateway does not support authorize()');
* }
* </code>
*
* For further code examples see the *omnipay-example* repository on github.
*
* @method static array all()
* @method static array replace(array $gateways)
* @method static string register(string $className)
* @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)
* @codingStandardsIgnoreEnd
*
* @see Omnipay\Common\GatewayFactory
*/
class Omnipay
{
/**
* Internal factory storage
*
* @var GatewayFactory
*/
private static $factory;
/**
* Get the gateway factory
*
* Creates a new empty GatewayFactory if none has been set previously.
*
* @return GatewayFactory A GatewayFactory instance
*/
public static function getFactory()
{
if (is_null(static::$factory)) {
static::$factory = new GatewayFactory;
}
return static::$factory;
}
/**
* Set the gateway factory
*
* @param GatewayFactory $factory A GatewayFactory instance
*/
public static function setFactory(GatewayFactory $factory = null)
{
static::$factory = $factory;
}
/**
* Static function call router.
*
* All other function calls to the Omnipay class are routed to the
* factory. e.g. Omnipay::getSupportedGateways(1, 2, 3, 4) is routed to the
* factory's getSupportedGateways method and passed the parameters 1, 2, 3, 4.
*
* Example:
*
* <code>
* // Create a gateway for the PayPal ExpressGateway
* $gateway = Omnipay::create('ExpressGateway');
* </code>
*
* @see GatewayFactory
*
* @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();
return call_user_func_array(array($factory, $method), $parameters);
}
}