From 28ee2a87d89d3a751713ace28041b01e64e826db Mon Sep 17 00:00:00 2001 From: kai-yu Date: Fri, 16 Sep 2016 17:38:55 +1000 Subject: [PATCH 1/3] add periodic api support --- README.md | 2 + src/Message/SecureXMLAbstractRequest.php | 88 +++++++++++++++++------- src/Message/SecureXMLResponse.php | 71 +++++++++++++++---- 3 files changed, 123 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index c891635..e1c9f59 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ [Omnipay](https://github.com/thephpleague/omnipay) is a framework agnostic, multi-gateway payment processing library for PHP 5.3+. This package implements SecurePay support for Omnipay. +A fork version of Ominipay SecurePay. The purpose of this repo is to support Periodic and Triggered API. + ## Installation Omnipay is installed via [Composer](http://getcomposer.org/). To install, simply add it diff --git a/src/Message/SecureXMLAbstractRequest.php b/src/Message/SecureXMLAbstractRequest.php index 7f1e386..0bac0db 100644 --- a/src/Message/SecureXMLAbstractRequest.php +++ b/src/Message/SecureXMLAbstractRequest.php @@ -9,10 +9,29 @@ abstract class SecureXMLAbstractRequest extends AbstractRequest { public $testEndpoint = 'https://test.securepay.com.au/xmlapi/payment'; public $liveEndpoint = 'https://api.securepay.com.au/xmlapi/payment'; + public $testPeriodicEndpoint = 'https://test.securepay.com.au/xmlapi/periodic'; + public $livePeriodicEndpoint = 'https://api.securepay.com.au/xmlapi/periodic'; protected $requestType = 'Payment'; protected $requiredFields = array(); + public function getEndpoint() + { + if ($this->getRequestType() == $this->requestType) { + return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint; + } else { + return $this->getTestMode() ? $this->testPeriodicEndpoint : $this->livePeriodicEndpoint; + } + } + + /** + * get request type + * + */ + public function getRequestType(){ + return $this->getCardReference() ? 'Periodic' : 'Payment'; + } + /** * Set the messageID on the request. * @@ -59,7 +78,11 @@ public function sendData($data) protected function getBaseXML() { foreach ($this->requiredFields as $field) { - $this->validate($field); + if ($field == 'card' && $this->getCardReference()){ + $this->validate('cardReference'); + } else { + $this->validate($field); + } } $xml = new \SimpleXMLElement(''); @@ -68,13 +91,17 @@ protected function getBaseXML() $messageInfo->messageID = $this->getMessageId(); $messageInfo->addChild('messageTimestamp', $this->generateTimestamp()); $messageInfo->addChild('timeoutValue', 60); - $messageInfo->addChild('apiVersion', 'xml-4.2'); + if($this->getCardReference()){ + $messageInfo->addChild('apiVersion', 'spxml-3.0'); + }else{ + $messageInfo->addChild('apiVersion', 'xml-4.2'); + } $merchantInfo = $xml->addChild('MerchantInfo'); $merchantInfo->addChild('merchantID', $this->getMerchantId()); $merchantInfo->addChild('password', $this->getTransactionPassword()); - $xml->addChild('RequestType', $this->requestType); // Not related to the transaction type + $xml->addChild('RequestType', $this->getRequestType()); // Not related to the transaction type return $xml; } @@ -87,18 +114,32 @@ protected function getBaseXML() protected function getBasePaymentXML() { $xml = $this->getBaseXML(); - - $payment = $xml->addChild('Payment'); - $txnList = $payment->addChild('TxnList'); - $txnList->addAttribute('count', 1); // One transaction per request supported by current API. - - $transaction = $txnList->addChild('Txn'); - $transaction->addAttribute('ID', 1); // One transaction per request supported by current API. - $transaction->addChild('txnType', $this->txnType); - $transaction->addChild('txnSource', 23); // Must always be 23 for SecureXML. - $transaction->addChild('amount', $this->getAmountInteger()); - $transaction->addChild('currency', $this->getCurrency()); - $transaction->purchaseOrderNo = $this->getTransactionId(); + $cardReference = $this->getCardReference(); + + if($cardReference) { + $periodic = $xml->addChild( 'Periodic' ); + $periodicList = $periodic->addChild( 'PeriodicList' ); + $periodicList->addAttribute('count', 1); + + $periodicItem = $periodicList->addChild( 'PeriodicItem' ); + $periodicItem->addAttribute('ID', 1); + $periodicItem->addChild('actionType', 'trigger'); + $periodicItem->addChild('clientID', $cardReference); + $periodicItem->addChild('amount', $this->getAmountInteger()); + $periodicItem->addChild('currency', $this->getCurrency()); + }else{ + $payment = $xml->addChild('Payment'); + $txnList = $payment->addChild('TxnList'); + $txnList->addAttribute('count', 1); // One transaction per request supported by current API. + + $transaction = $txnList->addChild('Txn'); + $transaction->addAttribute('ID', 1); // One transaction per request supported by current API. + $transaction->addChild('txnType', $this->txnType); + $transaction->addChild('txnSource', 23); // Must always be 23 for SecureXML. + $transaction->addChild('amount', $this->getAmountInteger()); + $transaction->addChild('currency', $this->getCurrency()); + $transaction->purchaseOrderNo = $this->getTransactionId(); + } return $xml; } @@ -109,15 +150,16 @@ protected function getBasePaymentXML() */ protected function getBasePaymentXMLWithCard() { - $this->getCard()->validate(); - $xml = $this->getBasePaymentXML(); - - $card = $xml->Payment->TxnList->Txn->addChild('CreditCardInfo'); - $card->addChild('cardNumber', $this->getCard()->getNumber()); - $card->addChild('cvv', $this->getCard()->getCvv()); - $card->addChild('expiryDate', $this->getCard()->getExpiryDate('m/y')); - + + if(!$this->getCardReference()) { + $this->getCard()->validate(); + + $card = $xml->Payment->TxnList->Txn->addChild('CreditCardInfo'); + $card->addChild('cardNumber', $this->getCard()->getNumber()); + $card->addChild('cvv', $this->getCard()->getCvv()); + $card->addChild('expiryDate', $this->getCard()->getExpiryDate('m/y')); + } return $xml; } diff --git a/src/Message/SecureXMLResponse.php b/src/Message/SecureXMLResponse.php index 786525f..55d5413 100644 --- a/src/Message/SecureXMLResponse.php +++ b/src/Message/SecureXMLResponse.php @@ -17,15 +17,29 @@ class SecureXMLResponse extends AbstractResponse public function isSuccessful() { // As per appendix F, 000 means the message was processed correctly - if ((string) $this->data->Status->statusCode !== '000' - || ($this->hasTransaction() - && (string) $this->data->Payment->TxnList->Txn->approved !== 'Yes')) { + if ( $this->isFailedCode() || $this->isNotApproved() ) { return false; } return true; } + private function isFailedCode() + { + return (string) $this->data->Status->statusCode !== '000' && (string) $this->data->Status->statusCode !== '0'; + } + + private function isNotApproved() + { + if ($this->hasTransaction()) + return (string) $this->data->Payment->TxnList->Txn->approved !== 'Yes'; + if ($this->hasPeriodic()) + return (string) $this->getResponseItem()->responseCode !== '00' + && (string) $this->getResponseItem()->responseCode !== '08' + && (string) $this->getResponseItem()->responseCode !== '77'; + return true; + } + /** * Determine if we have had payment information returned. * @@ -39,6 +53,33 @@ protected function hasTransaction() return isset($this->data->Payment->TxnList->Txn); } + /** + * Determine if we have had periodic payment information returned. + * + * @note For certain errors a Periodic element is returned but has an empty + * TxnList so this will tell us if we actually have a transaction to check. + * + * @return bool True if we have a transaction. + */ + protected function hasPeriodic() + { + return isset($this->data->Periodic->PeriodicList->PeriodicItem); + } + + /** + * Return the response item, transaction or periodicItem or null + * + * @return transaction or periodicItem or null + */ + protected function getResponseItem() + { + if ($this->hasTransaction()) + return $this->data->Payment->TxnList->Txn; + if ($this->hasPeriodic()) + return $this->data->Periodic->PeriodicList->PeriodicItem; + return null; + } + /** * @link https://www.securepay.com.au/_uploads/files/SecurePay_Response_Codes.pdf * @@ -46,9 +87,9 @@ protected function hasTransaction() */ public function getCode() { - return $this->hasTransaction() - ? (string) $this->data->Payment->TxnList->Txn->responseCode - : (string) $this->data->Status->statusCode; + if ($this->hasTransaction() || $this->hasPeriodic()) + return (string) $this->getResponseItem()->responseCode; + return (string) $this->data->Status->statusCode; } /** @@ -57,9 +98,9 @@ public function getCode() */ public function getMessage() { - return $this->hasTransaction() - ? (string) $this->data->Payment->TxnList->Txn->responseText - : (string) $this->data->Status->statusDescription; + if ($this->hasTransaction() || $this->hasPeriodic()) + return (string) $this->getResponseItem()->responseText; + return (string) $this->data->Status->statusDescription; } /** @@ -67,9 +108,9 @@ public function getMessage() */ public function getTransactionReference() { - return $this->hasTransaction() - ? (string) $this->data->Payment->TxnList->Txn->txnID - : null; + if ($this->hasTransaction() || $this->hasPeriodic()) + return (string) $this->getResponseItem()->txnID; + return null; } /** @@ -78,8 +119,8 @@ public function getTransactionReference() */ public function getSettlementDate() { - return $this->hasTransaction() - ? (string) $this->data->Payment->TxnList->Txn->settlementDate - : null; + if ($this->hasTransaction() || $this->hasPeriodic()) + return (string) $this->getResponseItem()->settlementDate; + return null; } } From 3378b717b2308e872fa56394948339e87c3628e1 Mon Sep 17 00:00:00 2001 From: kai-yu Date: Thu, 15 Dec 2016 11:47:23 +1100 Subject: [PATCH 2/3] Add creation and deletion of payor --- src/Message/SecureXMLAddPayorRequest.php | 26 +++++++++++++++++++++ src/Message/SecureXMLDeletePayorRequest.php | 24 +++++++++++++++++++ src/SecureXMLGateway.php | 10 ++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/Message/SecureXMLAddPayorRequest.php create mode 100644 src/Message/SecureXMLDeletePayorRequest.php diff --git a/src/Message/SecureXMLAddPayorRequest.php b/src/Message/SecureXMLAddPayorRequest.php new file mode 100644 index 0000000..9f90b85 --- /dev/null +++ b/src/Message/SecureXMLAddPayorRequest.php @@ -0,0 +1,26 @@ +getBasePaymentXML(); + + $xml = $this->getCardXML($xml); + + $xml->Periodic->PeriodicList->PeriodicItem->addChild('periodicType', 4); + + return $xml; + } +} diff --git a/src/Message/SecureXMLDeletePayorRequest.php b/src/Message/SecureXMLDeletePayorRequest.php new file mode 100644 index 0000000..63bb51a --- /dev/null +++ b/src/Message/SecureXMLDeletePayorRequest.php @@ -0,0 +1,24 @@ +getBasePaymentXML(); + + $xml->Periodic->PeriodicList->PeriodicItem->addChild('periodicType', 4); + + return $xml; + } +} diff --git a/src/SecureXMLGateway.php b/src/SecureXMLGateway.php index 444cdd3..6f42e3d 100644 --- a/src/SecureXMLGateway.php +++ b/src/SecureXMLGateway.php @@ -107,4 +107,14 @@ 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\SecureXMLAddPayorRequest', $parameters); + } + + public function deleteCard(array $parameters = array()) + { + return $this->createRequest('\Omnipay\SecurePay\Message\SecureXMLDeletePayorRequest', $parameters); + } } From 5635d71b34d258cbb4b08bb4228d9fcf0f9bd461 Mon Sep 17 00:00:00 2001 From: Mischa King Date: Mon, 16 Nov 2020 11:49:14 +1000 Subject: [PATCH 3/3] Updated Add Payor Request --- src/Message/SecureXMLAddPayorRequest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Message/SecureXMLAddPayorRequest.php b/src/Message/SecureXMLAddPayorRequest.php index 9f90b85..f524d52 100644 --- a/src/Message/SecureXMLAddPayorRequest.php +++ b/src/Message/SecureXMLAddPayorRequest.php @@ -10,16 +10,20 @@ */ class SecureXMLAddPayorRequest extends SecureXMLAbstractRequest { - protected $actionType = 'add'; + protected $actionType = 'add'; protected $requiredFields = array('amount', 'card', 'currency'); public function getData() { $xml = $this->getBasePaymentXML(); - $xml = $this->getCardXML($xml); + $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')); $xml->Periodic->PeriodicList->PeriodicItem->addChild('periodicType', 4); + $xml->Periodic->PeriodicList->PeriodicItem->actionType = 'add'; return $xml; }