Skip to content

Commit

Permalink
Add more features
Browse files Browse the repository at this point in the history
  • Loading branch information
bakura10 committed Nov 23, 2013
1 parent 332a75e commit ad8f228
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 2 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ try {
'token' => '1234'
));
} catch (\ZfrPaymill\Exception\TransactionErrorException $exception) {
// Seems the transaction failed
// Seems the transaction failed, let's see why:
$why = $exception->getMessage();

// Let's also get the response to have more info:
$response = $exception->getResponse();
} catch (\Exception $exception) {
// Catch any other exception...
}
Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
"php": ">=5.3.3",
"guzzle/guzzle": ">=3.5,<=3.8"
},
"require-dev": {
"phpunit/phpunit": "~3.7"
},
"autoload": {
"psr-0": {
"ZfrPaymill\\": "src/"
Expand Down
11 changes: 11 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<phpunit bootstrap="./tests/Bootstrap.php" colors="true">
<testsuite name="ZfrPaymill tests">
<directory>./tests</directory>
</testsuite>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
</phpunit>
110 changes: 110 additions & 0 deletions src/ZfrPaymill/Client/Listener/ErrorHandlerListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrPaymill\Listener;

use Guzzle\Common\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use ZfrPaymill\Exception\TransactionErrorException;

/**
* Performs additional checks for errors
*
* ZfrPaymill already takes care to throw an exception if a status code different than 200 is returned. However,
* Paymill may generate errors even if returning 200, for instance for transactions
*
* @author Michaël Gallego <[email protected]>
* @licence MIT
*/
class ErrorHandlerListener implements EventSubscriberInterface
{
/**
* List of error codes
*
* @var array
*/
private $errorCodes = array(
10001 => "General undefined response.",
10002 => "Still waiting on something.",
20000 => "General success response.",
40000 => "General problem with data.",
40001 => "General problem with payment data.",
40100 => "Problem with credit card data.",
40101 => "Problem with cvv.",
40102 => "Card expired or not yet valid.",
40103 => "Limit exceeded.",
40104 => "Card invalid.",
40105 => "Expiry date not valid.",
40106 => "Credit card brand required.",
40200 => "Problem with bank account data.",
40201 => "Bank account data combination mismatch.",
40202 => "User authentication failed.",
40300 => "Problem with 3d secure data.",
40301 => "Currency / amount mismatch",
40400 => "Problem with input data.",
40401 => "Amount too low or zero.",
40402 => "Usage field too long.",
40403 => "Currency not allowed.",
50000 => "General problem with backend.",
50001 => "Country blacklisted.",
50100 => "Technical error with credit card.",
50101 => "Error limit exceeded.",
50102 => "Card declined by authorization system.",
50103 => "Manipulation or stolen card.",
50104 => "Card restricted.",
50105 => "Invalid card configuration data.",
50200 => "Technical error with bank account.",
50201 => "Card blacklisted.",
50300 => "Technical error with 3D secure.",
50400 => "Decline because of risk issues.",
50500 => "General timeout.",
50501 => "Timeout on side of the acquirer.",
50502 => "Risk management transaction timeout.",
50600 => "Duplicate transaction.",
);

/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array('command.after_send' => 'handleError');
}

/**
* @param Event $event
* @return void
* @throws TransactionErrorException
*/
public function handleError(Event $event)
{
/* @var \Guzzle\Service\Command\CommandInterface $command */
$command = $event['command'];
$result = $command->toArray();

$code = isset($result['data']['response_code']) ? $result['data']['response_code'] : 10001;

if ($code >= 40000) {
$exception = new TransactionErrorException($this->errorCodes[$code], $code);
$exception->setRequest($command->getRequest());
$exception->setResponse($command->getResponse());

throw new $exception;
}
}
}
4 changes: 3 additions & 1 deletion src/ZfrPaymill/Client/PaymillClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
* and is licensed under the MIT license.
*/

namespace ZfrPaymill;
namespace ZfrPaymill\Client;

use Guzzle\Common\Event;
use Guzzle\Plugin\ErrorResponse\ErrorResponsePlugin;
use Guzzle\Service\Client;
use Guzzle\Service\Description\ServiceDescription;
use ZfrPaymill\Listener\ErrorHandlerListener;

/**
* @author Michaël Gallego <[email protected]>
Expand Down Expand Up @@ -123,6 +124,7 @@ public function __construct($apiKey, $version = self::LATEST_API_VERSION)

$dispatcher->addListener('command.before_send', array($this, 'authorizeRequest'));
$dispatcher->addSubscriber(new ErrorResponsePlugin());
$dispatcher->addSubscriber(new ErrorHandlerListener());
}

/**
Expand Down
28 changes: 28 additions & 0 deletions tests/Bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/

if (
!($loader = @include __DIR__ . '/../vendor/autoload.php')
&& !($loader = @include __DIR__ . '/../../../autoload.php')
) {
throw new RuntimeException('vendor/autoload.php could not be found. Did you run `php composer.phar install`?');
}

/* @var $loader \Composer\Autoload\ClassLoader */
$loader->add('ZfrPaymillTest\\', __DIR__);
70 changes: 70 additions & 0 deletions tests/ZfrPaymillTest/Client/PaymillClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace ZfrPaymillTest\Client;

use PHPUnit_Framework_TestCase;
use ZfrPaymill\Client\PaymillClient;

class PaymillClientTest extends PHPUnit_Framework_TestCase
{
/**
* @var PusherClient
*/
protected $client;

/**
* @var Credentials
*/
protected $credentials;

public function setUp()
{
$this->credentials = new Credentials('3', '278d425bdf160c739803', '7ad3773142a6692b25b8');
$this->client = new PusherClient($this->credentials);
}

/**
* @covers PusherClient::__construct
*/
public function testAssertApplicationIdIsAlwaysSent()
{
$config = $this->client->getConfig('command.params');
$this->assertEquals($config['app_id'], $this->credentials->getAppId());
}

/**
* @covers PusherClient::getApiVersion
*/
public function testCanRetrieveApiVersion()
{
$this->assertEquals('1.0', $this->client->getApiVersion());
}

/**
* @covers PusherClient
*/
public function testUserAgentIsIncluded()
{
// Make sure the user agent contains "pusher-php"
$command = $this->client->getCommand('GetChannelsInfo');
$request = $command->prepare();
$this->client->dispatch('command.before_send', array('command' => $command));
$this->assertRegExp('/^zfr-pusher-php/', (string)$request->getHeader('User-Agent', true));
}
}

0 comments on commit ad8f228

Please sign in to comment.