Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.

GP-685 - error handling and username fixes #8

Merged
merged 2 commits into from
Aug 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Omnipay/WorldpayCGHosted/Message/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function __construct($data, $notificationOriginIp)
}

$document = simplexml_import_dom($responseDom->documentElement);
$this->data = $document->notify->orderStatusEvent;
$this->data = $document->notify;
}

/**
Expand All @@ -62,15 +62,15 @@ public function getStatus()
return null;
}

return $this->data->payment->lastEvent->__toString();
return $this->getOrder()->payment->lastEvent->__toString();
}

/**
* @return bool
*/
public function hasStatus()
{
return !empty($this->data->payment->lastEvent);
return !empty($this->getOrder()->payment->lastEvent);
}

/**
Expand Down
23 changes: 22 additions & 1 deletion src/Omnipay/WorldpayCGHosted/Message/PurchaseRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,27 @@ public function setMerchant($value)
return $this->setParameter('merchant', $value);
}

/**
* Get the separate username if configured (more secure approach for basic auth) or fallback to merchant if not
*
* @return string
*/
public function getUsername()
{
return $this->parameters->get('username', $this->getParameter('merchant'));
}

/**
* Set basic auth username
*
* @param string $value
* @return AbstractRequest
*/
public function setUsername($value)
{
return $this->setParameter('username', $value);
}

/**
* Get pa response
*
Expand Down Expand Up @@ -277,7 +298,7 @@ public function sendData($data)
$document->appendChild($node);

$authorisation = base64_encode(
$this->getMerchant() . ':' . $this->getPassword()
$this->getUsername() . ':' . $this->getPassword()
);

$headers = [
Expand Down
2 changes: 1 addition & 1 deletion src/Omnipay/WorldpayCGHosted/Message/RedirectResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function getRedirectMethod()
*/
public function getRedirectUrl()
{
$url = $this->data->reference->__toString();
$url = $this->getOrder()->reference->__toString();

// Custom result URLs available: http://bit.ly/2uRpuX0
if (!empty($this->successUrl)) {
Expand Down
48 changes: 32 additions & 16 deletions src/Omnipay/WorldpayCGHosted/Message/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class Response extends AbstractResponse
{
use ResponseTrait;

/** @noinspection PhpMissingParentConstructorInspection */
/**
* @param RequestInterface $request Request
* @param string $data Data
Expand All @@ -25,15 +24,21 @@ public function __construct(RequestInterface $request, $data)
$this->request = $request;

if (empty($data)) {
throw new InvalidResponseException();
throw new InvalidResponseException('Empty data received');
}

$responseDom = new DOMDocument;
$responseDom->loadXML($data);
if (!@$responseDom->loadXML($data)) {
throw new InvalidResponseException('Non-XML notification response received');
}

$this->data = simplexml_import_dom(
$responseDom->documentElement->firstChild->firstChild
$this->data = @simplexml_import_dom(
$responseDom->documentElement->firstChild // <notify> or <reply>
);

if (empty($this->data)) {
throw new InvalidResponseException('Could not import response XML: ' . $data);
}
}

/**
Expand Down Expand Up @@ -91,27 +96,38 @@ public function getMessage()
97 => 'SECURITY BREACH'
];

$message = 'PENDING';

if (isset($this->data->error)) {
$message = 'ERROR: ' . $this->data->error;
return 'ERROR: ' . $this->data->error; // Cast to string to get CDATA content
}

if (isset($this->data->payment->ISO8583ReturnCode)) {
$returnCode = $this->data->payment->ISO8583ReturnCode->attributes();
$payment = $this->getOrder()->payment;
if (isset($payment->ISO8583ReturnCode)) {
$returnCode = $payment->ISO8583ReturnCode->attributes();

foreach ($returnCode as $name => $value) {
if ($name == 'code') {
$message = $codes[intval($value)];
return $codes[intval($value)];
}
}
}

if ($this->isSuccessful()) {
$message = $codes[0];
return $codes[0];
}

return 'PENDING';
}

/**
* @return string|null
*/
public function getErrorCode()
{
if (!isset($this->data->error) || empty($this->data->error->attributes()['code'])) {
return null;
}

return $message;
return (string) $this->data->error->attributes()['code'];
}

/**
Expand All @@ -121,7 +137,7 @@ public function getMessage()
*/
public function isRedirect()
{
return (isset($this->data->reference));
return (isset($this->getOrder()->reference));
}

/**
Expand All @@ -131,11 +147,11 @@ public function isRedirect()
*/
public function getTransactionReference()
{
if (empty($this->data->reference)) {
if (empty($this->getOrder()->reference)) {
return null;
}

$attributes = $this->data->reference->attributes();
$attributes = $this->getOrder()->reference->attributes();

if (isset($attributes['id'])) {
return $attributes['id'];
Expand Down
31 changes: 21 additions & 10 deletions src/Omnipay/WorldpayCGHosted/Message/ResponseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
/**
* Encapsulates response-like behaviour shared between actual Worldpay response objects and notifications, which
* actually come in Worldpay-initiated requests.
*
* @method \SimpleXMLElement|null getData()
*/
trait ResponseTrait
{
Expand All @@ -28,11 +26,11 @@ trait ResponseTrait
*/
public function getTransactionId()
{
if (empty($this->getData())) {
if (empty($this->getOrder())) {
return null;
}

$attributes = $this->getData()->attributes();
$attributes = $this->getOrder()->attributes();

if (isset($attributes['orderCode'])) {
return $attributes['orderCode'];
Expand All @@ -48,12 +46,12 @@ public function getTransactionId()
*/
public function isSuccessful()
{
if (!isset($this->getData()->payment->lastEvent)) {
if (!isset($this->getOrder()->payment->lastEvent)) {
return false;
}

return in_array(
strtoupper($this->getData()->payment->lastEvent),
strtoupper($this->getOrder()->payment->lastEvent),
[
self::$PAYMENT_STATUS_AUTHORISED,
self::$PAYMENT_STATUS_CAPTURED,
Expand All @@ -70,12 +68,12 @@ public function isSuccessful()
*/
public function isPending()
{
if (!isset($this->getData()->payment->lastEvent)) {
if (!isset($this->getOrder()->payment->lastEvent)) {
return false;
}

return in_array(
strtoupper($this->getData()->payment->lastEvent),
strtoupper($this->getOrder()->payment->lastEvent),
[
self::$PAYMENT_STATUS_SENT_FOR_AUTHORISATION,
],
Expand All @@ -90,16 +88,29 @@ public function isPending()
*/
public function isCancelled()
{
if (!isset($this->getData()->payment->lastEvent)) {
if (!isset($this->getOrder()->payment->lastEvent)) {
return false;
}

return in_array(
strtoupper($this->getData()->payment->lastEvent),
strtoupper($this->getOrder()->payment->lastEvent),
[
self::$PAYMENT_STATUS_CANCELLED,
],
true
);
}

public function getOrder()
{
if (isset($this->data->orderStatusEvent)) {
return $this->data->orderStatusEvent; // Notifications
}

if (isset($this->data->orderStatus)) {
return $this->data->orderStatus; // Order responses
}

return null;
}
}
11 changes: 0 additions & 11 deletions tests/Omnipay/WorldpayCGHosted/Message/NotificationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public function testAuthorisedValid()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertTrue($notification->isAuthorised());
Expand All @@ -39,7 +38,6 @@ public function testSentForAuthorisationValid()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand All @@ -60,7 +58,6 @@ public function testAuthorisedFromBadIp()
$http->getBody(),
self::ORIGIN_IP_BAD
);
$notification->getData();

$this->assertFalse($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand All @@ -81,7 +78,6 @@ public function testAuthorisedFromInvalidIp()
$http->getBody(),
'not-a-real-ip'
);
$notification->getData();

$this->assertFalse($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand All @@ -102,7 +98,6 @@ public function testAuthorisedFromMissingIp()
$http->getBody(),
'' // no origin IP
);
$notification->getData();

$this->assertFalse($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand All @@ -126,7 +121,6 @@ public function testAuthorisedMissingOrderCode()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertTrue($notification->isAuthorised());
Expand All @@ -150,7 +144,6 @@ public function testCaptured()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertTrue($notification->isAuthorised());
Expand All @@ -171,7 +164,6 @@ public function testRefused()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand All @@ -192,7 +184,6 @@ public function testCancelled()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand All @@ -213,7 +204,6 @@ public function testRefundRequest()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertTrue($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand Down Expand Up @@ -246,7 +236,6 @@ public function testUnexpectedXmlBody()
$http->getBody(),
self::ORIGIN_IP_VALID
);
$notification->getData();

$this->assertFalse($notification->isValid());
$this->assertFalse($notification->isAuthorised());
Expand Down
Loading