Skip to content

Commit

Permalink
Issue #104: make service and action methods.
Browse files Browse the repository at this point in the history
There were both properties previously. Moved to methods for
a more dynamic use, where the service can change according to
a modifying parameter.

Removed __construct() from Response, as we are only passing
an array in as data now to initialise, and not a body object.
This was a legacy left-over, and good to finally remove it.
  • Loading branch information
judgej committed Sep 17, 2018
1 parent 3fdc10b commit 14a1424
Show file tree
Hide file tree
Showing 22 changed files with 246 additions and 98 deletions.
29 changes: 24 additions & 5 deletions src/ConstantsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,37 @@ interface ConstantsInterface
const ACCOUNT_TYPE_M = 'M';
const ACCOUNT_TYPE_C = 'C';

//
// Then the response constants.
//

/**
* The raw transaction type the response is a part of
* The transaction type.
* These will usually be returned in the response matching the
* request.
* @var string
*/
const TXTYPE_PAYMENT = 'PAYMENT';
const TXTYPE_DEFERRED = 'DEFERRED';
const TXTYPE_AUTHENTICATE = 'AUTHENTICATE';
const TXTYPE_REMOVETOKEN = 'REMOVETOKEN';
const TXTYPE_TOKEN = 'TOKEN';
const TXTYPE_RELEASE = 'RELEASE';
const TXTYPE_AUTHORISE = 'AUTHORISE';
const TXTYPE_VOID = 'VOID';
const TXTYPE_ABORT = 'ABORT';
const TXTYPE_REFUND = 'REFUND';
const TXTYPE_REPEAT = 'REPEAT';
const TXTYPE_REPEATDEFERRED = 'REPEATDEFERRED';

/**
*
*/
const SERVICE_SERVER_REGISTER = 'vspserver-register';
const SERVICE_DIRECT_REGISTER = 'vspdirect-register';
const SERVICE_REPEAT = 'repeat';
const SERVICE_TOKEN = 'directtoken';
const SERVICE_DIRECT3D = 'direct3dcallback';

//
// Then the response constants.
//

/**
* There are a wide range of status codes across the different gatweay types
Expand Down
1 change: 1 addition & 0 deletions src/DirectGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function getDefaultParameters()
'useOldBasketFormat' => false,
'exitOnResponse' => false,
'apply3DSecure' => null,
'useAuthenticate' => null,
];
}

Expand Down
50 changes: 31 additions & 19 deletions src/Message/AbstractRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ abstract class AbstractRequest extends OmnipayAbstractRequest implements Constan
{
use GatewayParamsTrait;

/**
* @var string The transaction type, used in the request body.
*/
protected $action;

/**
* @var string The service name, used in the endpoint URL.
*/
Expand Down Expand Up @@ -53,24 +48,25 @@ public function setIframe($value)

/**
* The name of the service used in the endpoint to send the message.
* For most services, the URL fragment will be the lower case version
* For MANY services, the URL fragment will be the lower case version
* of the action.
*
* @return string Sage Pay endpoint service name.
*/
public function getService()
{
return ($this->service ?: strtolower($this->action));
return strtolower($this->getTxType());
}

/**
* @return string the transaction type, if one is relevant for this message.
* If it is used, i.e. needed for an enpoint, then it must be defined.
*
* @return string the transaction type.
* @throws InvalidRequestException
*/
public function getTxType()
{
if (isset($this->action)) {
return $this->action;
}
throw new InvalidRequestException('Transactino type not defined.');
}

/**
Expand Down Expand Up @@ -128,27 +124,43 @@ public function sendData($data)
'POST',
$this->getEndpoint(),
[
'Content-Type' => 'application/x-www-form-urlencoded'
'Content-Type' => 'application/x-www-form-urlencoded',
],
http_build_query($data)
);

// The body is a string.
$body = $httpResponse->getBody();
// We might want to check $httpResponse->getStatusCode()

// Split into lines.
$lines = preg_split('/[\n\r]+/', $body);
$responseData = static::parseBodyData($httpResponse);

$responseData = array();
return $this->createResponse($responseData);
}

/**
* The payload consists of name=>value pairs, each on a separate line.
*
* @param ??? $httpResponse
* @return array
*/
public static function parseBodyData($httpResponse)
{
$bodyText = (string)$httpResponse->getBody();

// Split the bodyText into lines.

$lines = preg_split('/[\n\r]+/', $bodyText);

$responseData = [];

foreach ($lines as $line) {
$line = explode('=', $line, 2);
if (!empty($line[0])) {

if (! empty($line[0])) {
$responseData[trim($line[0])] = isset($line[1]) ? trim($line[1]) : '';
}
}

return $this->createResponse($responseData);
return $responseData;
}

/**
Expand Down
20 changes: 17 additions & 3 deletions src/Message/DirectAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

class DirectAuthorizeRequest extends AbstractRequest
{
protected $action = 'DEFERRED';
protected $service = 'vspdirect-register';

/**
* @var array Some mapping from Omnipay card brand codes to Sage Pay card branc codes.
*/
Expand All @@ -19,6 +16,23 @@ class DirectAuthorizeRequest extends AbstractRequest
'diners_club' => 'DC'
);

/**
* @return string the transaction type
*/
public function getTxType()
{
if ($this->getUseAuthenticate()) {
return static::TXTYPE_AUTHENTICATE;
} else {
return static::TXTYPE_DEFERRED;
}
}

public function getService()
{
return static::SERVICE_DIRECT_REGISTER;
}

/**
* The required fields concerning what is being authorised and who
* it is being authorised for.
Expand Down
2 changes: 1 addition & 1 deletion src/Message/DirectCompleteAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class DirectCompleteAuthorizeRequest extends AbstractRequest
{
public function getService()
{
return 'direct3dcallback';
return static::SERVICE_DIRECT3D;
}

public function getData()
Expand Down
5 changes: 4 additions & 1 deletion src/Message/DirectPurchaseRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@
*/
class DirectPurchaseRequest extends DirectAuthorizeRequest
{
protected $action = 'PAYMENT';
public function getService()
{
return static::SERVICE_DIRECT_REGISTER;
}
}
17 changes: 10 additions & 7 deletions src/Message/DirectTokenRegistrationRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@

class DirectTokenRegistrationRequest extends AbstractRequest
{
protected $action = 'TOKEN';

protected $cardBrandMap = array(
'mastercard' => 'mc',
'diners_club' => 'dc'
);

public function getService()
{
return static::SERVICE_TOKEN;
}

public function getTxType()
{
return static::TXTYPE_TOKEN;
}

public function getData()
{
$this->validate('card');
Expand All @@ -35,11 +43,6 @@ public function getData()
return $data;
}

public function getService()
{
return 'directtoken';
}

protected function getCardBrand()
{
$brand = $this->getCard()->getBrand();
Expand Down
32 changes: 3 additions & 29 deletions src/Message/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,16 @@ class Response extends AbstractResponse implements RedirectResponseInterface, Co
{
use ResponseFieldsTrait;

/**
* FIXME: The response should never be directly passed the raw HTTP
* body like this. The body should be parsed to data before instantiation.
* However, the tests do not do that. I believe it is the tests that are broken,
* but the tests are how the interface has been implemented so we cannot break
* that for people who may rely on it.
*/
public function __construct(RequestInterface $request, $data)
{
$this->request = $request;

if (!is_array($data)) {
// Split the data (string or guzzle body object) into lines.
$lines = preg_split('/[\n\r]+/', (string)$data);

$data = array();

foreach ($lines as $line) {
$line = explode('=', $line, 2);
if (!empty($line[0])) {
$data[trim($line[0])] = isset($line[1]) ? trim($line[1]) : '';
}
}
}

$this->data = $data;
}

/**
* CHECKME: should we include "OK REPEATED" as a successful status too?
*
* @return bool True if the transaction is successful and complete.
*/
public function isSuccessful()
{
return $this->getStatus() === static::SAGEPAY_STATUS_OK;
return $this->getStatus() === static::SAGEPAY_STATUS_OK
|| $this->getStatus() === static::SAGEPAY_STATUS_REGISTERED
|| $this->getStatus() === static::SAGEPAY_STATUS_AUTHENTICATED;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/Message/ServerAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
*/
class ServerAuthorizeRequest extends DirectAuthorizeRequest
{
protected $service = 'vspserver-register';
public function getService()
{
return static::SERVICE_SERVER_REGISTER;
}

/**
* Add the optional token details to the base data.
Expand Down
10 changes: 8 additions & 2 deletions src/Message/ServerPurchaseRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
*/
class ServerPurchaseRequest extends ServerAuthorizeRequest
{
protected $action = 'PAYMENT';

public function getData()
{
$data = parent::getData();

return $data;
}

/**
* @return string the transaction type
*/
public function getTxType()
{
return static::TXTYPE_PAYMENT;
}
}
5 changes: 4 additions & 1 deletion src/Message/ServerTokenRegistrationRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

class ServerTokenRegistrationRequest extends AbstractRequest
{
protected $action = 'TOKEN';
public function getTxType()
{
return static::TXTYPE_TOKEN;
}

/**
* @return mixed
Expand Down
5 changes: 4 additions & 1 deletion src/Message/SharedAbortRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@
*/
class SharedAbortRequest extends SharedVoidRequest
{
protected $action = 'ABORT';
public function getTxType()
{
return static::TXTYPE_ABORT;
}
}
Loading

0 comments on commit 14a1424

Please sign in to comment.