Skip to content

Added ability to use SecurePay's stored card functions using createCard/updateCard/deleteCard #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text eol=lf
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
composer.lock
composer.phar
phpunit.xml
.idea
29 changes: 27 additions & 2 deletions src/Message/SecureXMLAbstractRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ abstract class SecureXMLAbstractRequest extends AbstractRequest
*/
protected $requiredFields = [];

/**
* @var array
*/
protected $apiVersion = 'xml-4.2';

/**
* Set the messageID on the request.
*
Expand Down Expand Up @@ -84,7 +89,7 @@ protected function getBaseXML()
$messageInfo->messageID = $this->getMessageId();
$messageInfo->addChild('messageTimestamp', $this->generateTimestamp());
$messageInfo->addChild('timeoutValue', 60);
$messageInfo->addChild('apiVersion', 'xml-4.2');
$messageInfo->addChild('apiVersion', $this->apiVersion);

$merchantInfo = $xml->addChild('MerchantInfo');
$merchantInfo->addChild('merchantID', $this->getMerchantId());
Expand Down Expand Up @@ -114,7 +119,27 @@ protected function getBasePaymentXML()
$transaction->addChild('txnSource', 23); // Must always be 23 for SecureXML.
$transaction->addChild('amount', $this->getAmountInteger());
$transaction->addChild('currency', $this->getCurrency());
$transaction->purchaseOrderNo = $this->getTransactionId();
$transaction->addChild('purchaseOrderNo', $this->getTransactionId());

return $xml;
}

/**
* XML template of a SecurePayMessage Payment using a stored card (Payor ID).
*
* @return \SimpleXMLElement SecurePayMessage with transaction details.
*/
protected function getBaseStoredCardXML($actionType)
{
$xml = $this->getBaseXML();

$periodic= $xml->addChild('Periodic');
$periodicList = $periodic->addChild('PeriodicList');
$periodicList->addAttribute('count', 1);
$periodicItem = $periodicList->addChild('PeriodicItem');
$periodicItem->addAttribute('ID', 1); // One transaction per request supported by current API.
$periodicItem->addChild('actionType', $actionType);
$periodicItem->addChild('clientID', $this->getCardReference());

return $xml;
}
Expand Down
40 changes: 40 additions & 0 deletions src/Message/SecureXMLDeleteCardRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Omnipay\SecurePay\Message;

/**
* SecurePay SecureXML Store Card Delete Request.
*
* Send a request to delete a stored PayorID from Securepay's system
*
* The cardReference must match the prior existing stored card.
*/
class SecureXMLDeleteCardRequest extends SecureXMLAbstractRequest
{
/**
* @var string
*/
public $testEndpoint = 'https://test.api.securepay.com.au/xmlapi/periodic';

/**
* @var string
*/
public $liveEndpoint = 'https://api.securepay.com.au/xmlapi/periodic';

protected $requiredFields = ['cardReference'];

/**
* @var string
*/
protected $requestType = 'Periodic';

/**
* @var string
*/
protected $apiVersion = 'spxml-4.2';

public function getData()
{
return $this->getBaseStoredCardXML('delete');
}
}
48 changes: 48 additions & 0 deletions src/Message/SecureXMLEditCardRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Omnipay\SecurePay\Message;

/**
* SecurePay SecureXML Store Card Update Request.
*
* Send a request to update the details a stored PayorID
*
* The cardReference must match the prior existing stored card.
*/
class SecureXMLEditCardRequest extends SecureXMLAbstractRequest
{
/**
* @var string
*/
public $testEndpoint = 'https://test.api.securepay.com.au/xmlapi/periodic';

/**
* @var string
*/
public $liveEndpoint = 'https://api.securepay.com.au/xmlapi/periodic';

protected $requiredFields = ['card', 'cardReference'];

/**
* @var string
*/
protected $requestType = 'Periodic';

/**
* @var string
*/
protected $apiVersion = 'spxml-4.2';

public function getData()
{
$xml = $this->getBaseStoredCardXML('edit');

$this->getCard()->validate();
$card = $xml->Periodic->PeriodicList->PeriodicItem->addChild('CreditCardInfo');
$card->addChild('cardNumber', $this->getCard()->getNumber());
$card->addChild('cvv', $this->getCard()->getCvv());
$card->addChild('expiryDate', $this->getCard()->getExpiryDate('m/y'));

return $xml;
}
}
37 changes: 32 additions & 5 deletions src/Message/SecureXMLResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ public function isSuccessful()
{
// As per appendix F, 000 means the message was processed correctly
if ((string) $this->data->Status->statusCode !== '000'
&& ((string) $this->data->Status->statusCode !== '0'
&& (string) $this->data->Status->statusDescription !== 'Normal')
|| ($this->hasTransaction()
&& (string) $this->data->Payment->TxnList->Txn->approved !== 'Yes')) {
&& (string) $this->data->Payment->TxnList->Txn->approved !== 'Yes')
|| ($this->hasPeriodic()
&& (string) $this->data->Periodic->PeriodicList->PeriodicItem->successful !== 'yes'
&& (string) $this->data->Periodic->PeriodicList->PeriodicItem->responseCode !== '00')) {
return false;
}

Expand All @@ -39,6 +44,20 @@ protected function hasTransaction()
return isset($this->data->Payment->TxnList->Txn);
}

/**
* Determine if we have had periodic information returned (for storage and retrieval of Payor IDs).\
*
* @return bool True if we have a periodic item.
*/
protected function hasPeriodic()
{
return (($this->data->RequestType == 'Periodic')
&& isset($this->data->Periodic)
&& isset($this->data->Periodic->PeriodicList)
&& isset($this->data->Periodic->PeriodicList->PeriodicItem)
);
}

/**
* @link https://www.securepay.com.au/_uploads/files/SecurePay_Response_Codes.pdf
*
Expand All @@ -48,7 +67,9 @@ public function getCode()
{
return $this->hasTransaction()
? (string) $this->data->Payment->TxnList->Txn->responseCode
: (string) $this->data->Status->statusCode;
: ($this->hasPeriodic()
? (string) $this->data->Periodic->PeriodicList->PeriodicItem->responseCode
: (string) $this->data->Status->statusCode);
}

/**
Expand All @@ -59,7 +80,9 @@ public function getMessage()
{
return $this->hasTransaction()
? (string) $this->data->Payment->TxnList->Txn->responseText
: (string) $this->data->Status->statusDescription;
: ($this->hasPeriodic()
? (string) $this->data->Periodic->PeriodicList->PeriodicItem->responseText
: (string) $this->data->Status->statusDescription);
}

/**
Expand All @@ -69,7 +92,9 @@ public function getTransactionReference()
{
return $this->hasTransaction()
? (string) $this->data->Payment->TxnList->Txn->txnID
: null;
: ($this->hasPeriodic()
? (string) $this->data->Periodic->PeriodicList->PeriodicItem->txnID
: null);
}

/**
Expand All @@ -80,6 +105,8 @@ public function getSettlementDate()
{
return $this->hasTransaction()
? (string) $this->data->Payment->TxnList->Txn->settlementDate
: null;
: ($this->hasPeriodic()
? (string) $this->data->Periodic->PeriodicList->PeriodicItem->settlementDate
: null);
}
}
53 changes: 53 additions & 0 deletions src/Message/SecureXMLStoreCardRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Omnipay\SecurePay\Message;

/**
* SecurePay SecureXML Store Card Request.
*
* Send a request to store the details a new credit card.
*
* The cardReference must be sent and must be unique in order to successfully create a new payor.
*/
class SecureXMLStoreCardRequest extends SecureXMLAbstractRequest
{
/**
* @var string
*/
public $testEndpoint = 'https://test.api.securepay.com.au/xmlapi/periodic';

/**
* @var string
*/
public $liveEndpoint = 'https://api.securepay.com.au/xmlapi/periodic';


protected $requiredFields = ['amount', 'card', 'cardReference'];

/**
* @var string
*/
protected $requestType = 'Periodic';

/**
* @var string
*/
protected $apiVersion = 'spxml-4.2';

public function getData()
{
$xml = $this->getBaseStoredCardXML('add');

$this->getCard()->validate();
$periodicItem = $xml->Periodic->PeriodicList->PeriodicItem;
$periodicItem->addChild('amount', $this->getAmountInteger());
$periodicItem->addChild('periodicType', 4); // Appendix A "Add a Payor ID"
$card = $periodicItem->addChild('CreditCardInfo');
$card->addChild('cardNumber', $this->getCard()->getNumber());
$card->addChild('cvv', $this->getCard()->getCvv());
$card->addChild('expiryDate', $this->getCard()->getExpiryDate('m/y'));
$card->addChild('recurringFlag', 'no');

return $xml;
}
}
46 changes: 46 additions & 0 deletions src/Message/SecureXMLStoredCardPurchaseRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Omnipay\SecurePay\Message;

/**
* SecurePay SecureXML Payment Using Stored Card.
*
* Perform a purchase using a stored card.
*
* The cardReference must be sent in order to successfully process the purchase
*/
class SecureXMLStoredCardPurchaseRequest extends SecureXMLAbstractRequest
{
/**
* @var string
*/
public $testEndpoint = 'https://test.api.securepay.com.au/xmlapi/periodic';

/**
* @var string
*/
public $liveEndpoint = 'https://api.securepay.com.au/xmlapi/periodic';

protected $requiredFields = ['amount', 'cardReference', 'transactionId'];

/**
* @var string
*/
protected $requestType = 'Periodic';

/**
* @var string
*/
protected $apiVersion = 'spxml-4.2';

public function getData()
{
$xml = $this->getBaseStoredCardXML('trigger');
$periodicItem = $xml->Periodic->PeriodicList->PeriodicItem;
$periodicItem->addChild('transactionReference', $this->getTransactionId());
$periodicItem->addChild('amount', $this->getAmountInteger());
$periodicItem->addChild('periodicType', 1); // Appendix A "Add a Payor ID"

return $xml;
}
}
18 changes: 18 additions & 0 deletions src/SecureXMLGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ public function capture(array $parameters = array())

public function purchase(array $parameters = array())
{
if (array_key_exists('cardReference', $parameters)) {
return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLStoredCardPurchaseRequest', $parameters);
}
return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLPurchaseRequest', $parameters);
}

Expand All @@ -107,4 +110,19 @@ public function echoTest(array $parameters = array())
{
return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLEchoTestRequest', $parameters);
}

public function createCard(array $parameters = array())
{
return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLStoreCardRequest', $parameters);
}

public function deleteCard(array $parameters = array())
{
return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLDeleteCardRequest', $parameters);
}

public function updateCard(array $parameters = array())
{
return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLEditCardRequest', $parameters);
}
}
Loading