From 7da5aa68054af57e812dc00ff292116e34c5e527 Mon Sep 17 00:00:00 2001 From: ekes Date: Wed, 9 Mar 2022 12:17:52 +0100 Subject: [PATCH 01/15] Don't throw fatal error if line item doesn't have a product item. --- src/Plugin/Commerce/PaymentGateway/SagepayCommon.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php b/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php index 8679ec2..e210f27 100644 --- a/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php +++ b/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php @@ -141,6 +141,9 @@ protected function getBasketFromProducts(OrderInterface $order) { /** @var ProductVariationInterface $product */ $product = $item->getPurchasedEntity(); + if (!$product) { + continue; + } if ($basket === FALSE) { $basket = new SagepayBasket(); From 227c6c35999833525b8ac98b3b7a4d01149909a7 Mon Sep 17 00:00:00 2001 From: ekes Date: Wed, 9 Mar 2022 16:11:10 +0100 Subject: [PATCH 02/15] Standardize line endings at least within the repo. --- src/Sagepay/classes/abstract_api.php | 714 +++--- src/Sagepay/classes/api_factory.php | 74 +- src/Sagepay/classes/basket.php | 1368 +++++------ src/Sagepay/classes/card_details.php | 304 +-- src/Sagepay/classes/customer.php | 570 ++--- src/Sagepay/classes/customer_details.php | 502 ++-- src/Sagepay/classes/direct_api.php | 254 +- src/Sagepay/classes/form_api.php | 156 +- src/Sagepay/classes/item.php | 1288 +++++----- src/Sagepay/classes/server_api.php | 230 +- src/Sagepay/classes/settings.php | 2870 +++++++++++----------- src/Sagepay/classes/surcharge.php | 254 +- src/Sagepay/classes/token.php | 352 +-- src/Sagepay/classes/valid.php | 444 ++-- src/Sagepay/classes/validator.php | 182 +- src/Sagepay/config.php | 296 +-- src/Sagepay/constants.php | 230 +- src/Sagepay/sagepay.php | 90 +- 18 files changed, 5089 insertions(+), 5089 deletions(-) diff --git a/src/Sagepay/classes/abstract_api.php b/src/Sagepay/classes/abstract_api.php index 0f84675..d94f55f 100755 --- a/src/Sagepay/classes/abstract_api.php +++ b/src/Sagepay/classes/abstract_api.php @@ -1,357 +1,357 @@ -config = $config; - $this->_createBasket(); - } - - /** - * Initialize Basket for current instance - */ - private function _createBasket() - { - $this->basket = new SagepayBasket(); - $this->basket->setAgentId($this->config->getVendorName()); - } - - /** - * Get config - * - * @return SagepaySettings - */ - public function getConfig() - { - return $this->config; - } - - /** - * Get integrationMethod - * - * @return string - */ - public final function getIntegrationMethod() - { - return $this->integrationMethod; - } - - /** - * Get basket - * - * @return SagepayBasket - */ - public final function getBasket() - { - return $this->basket; - } - - /** - * Set basket - * - * @param SagepayBasket $basket - */ - public final function setBasket(SagepayBasket $basket) - { - $this->basket = $basket; - } - - /** - * Set txType - * - * @param string $txType - */ - public final function setTxType($txType) - { - $this->txType = $txType; - } - - /** - * Get txType - * - * @return string - */ - public final function getTxType() - { - return $this->config->getTxType(); - } - - /** - * Get addressList - * - * @return SagepayCustomerDetails[] - */ - public final function getAddressList() - { - return $this->addressList; - } - - /** - * Set addressList - * - * @param SagepayCustomerDetails[] $addressList - */ - public final function setAddressList($addressList) - { - $this->addressList = $addressList; - } - - /** - * Add a set of customer details to addressList - * - * @param SagepayCustomerDetails $address - */ - public final function addAddress(SagepayCustomerDetails $address) - { - $this->addressList[] = $address; - } - - /** - * Get paneValues - * - * @return array - */ - public final function getPaneValues() - { - return $this->paneValues; - } - - /** - * Set paneValues - * - * @param array $paneValues - */ - public final function setPaneValues($paneValues) - { - $this->paneValues = $paneValues; - } - - /** - * Get Customer information - * - * @return SagepayCustomer - */ - public function getCustomer() - { - return $this->customer; - } - - /** - * Set Customer information - * - * @param SagepayCustomer $customer - */ - public function setCustomer(SagepayCustomer $customer) - { - $this->customer = $customer; - } - - /** - * Set data - * - * @param array $data - */ - public final function setData(array $data) - { - $this->data = $data; - } - - /** - * Get data - * - * @return array - */ - public final function getData() - { - return $this->data; - } - - /** - * Add a field to data - * - * @param string $field - * @param mixed $value - */ - public final function setDataField($field, $value = null) - { - $this->data[$field] = $value; - } - - /** - * Update data values - * - * @param array $data - */ - public final function updateData(array $data) - { - $this->data = array_merge($this->data, $data); - } - - /** - * Sort data in required order - */ - protected function sortData() - { - $unsorted = $this->data; - $data = array(); - foreach ($this->mandatory as $key) - { - $data[$key] = $unsorted[$key]; - unset($unsorted[$key]); - } - $data += $unsorted; - $this->data = $data; - } - - /** - * Check required fields that will be sent to gateway - * - * @throws SagepayApiException - */ - protected function checkMandatoryFields() - { - $emptyFields = array(); - - foreach ($this->mandatory as $value) - { - if (is_null($this->data[$value])) - { - $emptyFields[] = $value; - } - } - - if (count($emptyFields)) - { - $fields = implode(', ', $emptyFields); - $beVerb = count($emptyFields) == 1 ? 'is' : 'are'; - throw new SagepayApiException($fields . ' ' . $beVerb . " empty"); - } - $this->sortData(); - } - - /** - * Populate data that is read from configurations - */ - protected function addConfiguredValues() - { - $data = array( - 'Vendor' => $this->config->getVendorName(), - 'VPSProtocol' => $this->config->getProtocolVersion(), - 'Currency' => $this->config->getCurrency(), - 'TxType' => $this->config->getTxType(), - 'SendEMail' => $this->config->getSendEmail(), - 'VendorEMail' => $this->config->getVendorEmail(), - 'Apply3DSecure' => $this->config->getApply3dSecure(), - 'ApplyAVSCV2' => $this->config->getApplyAvsCv2(), - ); - - $partnerId = $this->config->getPartnerId(); - if (!empty($partnerId)) - { - $data['ReferrerID'] = $partnerId; - } - if ($data['SendEMail'] == 1) - { - $data['eMailMessage'] = $this->config->getEmailMessage(); - } - $allowGiftAid = $this->config->getAllowGiftAid(); - if (!isset($this->data['AllowGiftAid'])) - { - $data['AllowGiftAid'] = $allowGiftAid; - } - - $this->updateData($data); - } - - /** - * Generate values for payment - * - * @return string[] - */ - abstract public function createRequest(); - - /** - * Generate UrlEncoded values - * - * @return string urlencoded data of request - */ - abstract public function getQueryData(); -} +config = $config; + $this->_createBasket(); + } + + /** + * Initialize Basket for current instance + */ + private function _createBasket() + { + $this->basket = new SagepayBasket(); + $this->basket->setAgentId($this->config->getVendorName()); + } + + /** + * Get config + * + * @return SagepaySettings + */ + public function getConfig() + { + return $this->config; + } + + /** + * Get integrationMethod + * + * @return string + */ + public final function getIntegrationMethod() + { + return $this->integrationMethod; + } + + /** + * Get basket + * + * @return SagepayBasket + */ + public final function getBasket() + { + return $this->basket; + } + + /** + * Set basket + * + * @param SagepayBasket $basket + */ + public final function setBasket(SagepayBasket $basket) + { + $this->basket = $basket; + } + + /** + * Set txType + * + * @param string $txType + */ + public final function setTxType($txType) + { + $this->txType = $txType; + } + + /** + * Get txType + * + * @return string + */ + public final function getTxType() + { + return $this->config->getTxType(); + } + + /** + * Get addressList + * + * @return SagepayCustomerDetails[] + */ + public final function getAddressList() + { + return $this->addressList; + } + + /** + * Set addressList + * + * @param SagepayCustomerDetails[] $addressList + */ + public final function setAddressList($addressList) + { + $this->addressList = $addressList; + } + + /** + * Add a set of customer details to addressList + * + * @param SagepayCustomerDetails $address + */ + public final function addAddress(SagepayCustomerDetails $address) + { + $this->addressList[] = $address; + } + + /** + * Get paneValues + * + * @return array + */ + public final function getPaneValues() + { + return $this->paneValues; + } + + /** + * Set paneValues + * + * @param array $paneValues + */ + public final function setPaneValues($paneValues) + { + $this->paneValues = $paneValues; + } + + /** + * Get Customer information + * + * @return SagepayCustomer + */ + public function getCustomer() + { + return $this->customer; + } + + /** + * Set Customer information + * + * @param SagepayCustomer $customer + */ + public function setCustomer(SagepayCustomer $customer) + { + $this->customer = $customer; + } + + /** + * Set data + * + * @param array $data + */ + public final function setData(array $data) + { + $this->data = $data; + } + + /** + * Get data + * + * @return array + */ + public final function getData() + { + return $this->data; + } + + /** + * Add a field to data + * + * @param string $field + * @param mixed $value + */ + public final function setDataField($field, $value = null) + { + $this->data[$field] = $value; + } + + /** + * Update data values + * + * @param array $data + */ + public final function updateData(array $data) + { + $this->data = array_merge($this->data, $data); + } + + /** + * Sort data in required order + */ + protected function sortData() + { + $unsorted = $this->data; + $data = array(); + foreach ($this->mandatory as $key) + { + $data[$key] = $unsorted[$key]; + unset($unsorted[$key]); + } + $data += $unsorted; + $this->data = $data; + } + + /** + * Check required fields that will be sent to gateway + * + * @throws SagepayApiException + */ + protected function checkMandatoryFields() + { + $emptyFields = array(); + + foreach ($this->mandatory as $value) + { + if (is_null($this->data[$value])) + { + $emptyFields[] = $value; + } + } + + if (count($emptyFields)) + { + $fields = implode(', ', $emptyFields); + $beVerb = count($emptyFields) == 1 ? 'is' : 'are'; + throw new SagepayApiException($fields . ' ' . $beVerb . " empty"); + } + $this->sortData(); + } + + /** + * Populate data that is read from configurations + */ + protected function addConfiguredValues() + { + $data = array( + 'Vendor' => $this->config->getVendorName(), + 'VPSProtocol' => $this->config->getProtocolVersion(), + 'Currency' => $this->config->getCurrency(), + 'TxType' => $this->config->getTxType(), + 'SendEMail' => $this->config->getSendEmail(), + 'VendorEMail' => $this->config->getVendorEmail(), + 'Apply3DSecure' => $this->config->getApply3dSecure(), + 'ApplyAVSCV2' => $this->config->getApplyAvsCv2(), + ); + + $partnerId = $this->config->getPartnerId(); + if (!empty($partnerId)) + { + $data['ReferrerID'] = $partnerId; + } + if ($data['SendEMail'] == 1) + { + $data['eMailMessage'] = $this->config->getEmailMessage(); + } + $allowGiftAid = $this->config->getAllowGiftAid(); + if (!isset($this->data['AllowGiftAid'])) + { + $data['AllowGiftAid'] = $allowGiftAid; + } + + $this->updateData($data); + } + + /** + * Generate values for payment + * + * @return string[] + */ + abstract public function createRequest(); + + /** + * Generate UrlEncoded values + * + * @return string urlencoded data of request + */ + abstract public function getQueryData(); +} diff --git a/src/Sagepay/classes/api_factory.php b/src/Sagepay/classes/api_factory.php index edf78ee..fe932bc 100755 --- a/src/Sagepay/classes/api_factory.php +++ b/src/Sagepay/classes/api_factory.php @@ -1,37 +1,37 @@ -_id = (string) time(); - } - - /** - * Get basket ID - * - * @return string - */ - public function getId() - { - return $this->_id; - } - - /** - * Set basket ID - * - * @param string $id - */ - public function setId($id) - { - if (SagepayValid::digit($id)) - { - $this->_id = (string) $id; - } - } - - /** - * Get description of goods purchased is displayed on the Sage Pay Form payment page as the customer enters their card details. - * - * @return string - */ - public function getDescription() - { - return $this->_description; - } - - /** - * Set basket description - * - * @param string $description - */ - public function setDescription($description) - { - $this->_description = substr($description, 0, 100); - } - - /** - * Get ID of the seller if using a phone payment. - * - * @return string - */ - public function getAgentId() - { - return $this->_agentId; - } - - /** - * Set ID of the seller if using a phone payment. - * - * @param string $agentId - */ - public function setAgentId($agentId) - { - if (SagepayValid::regex($agentId, '/^[a-zA-Z0-9\ ]{1,16}$/')) - { - $this->_agentId = $agentId; - } - } - - /** - * Get list of items - * - * @return SagepayItem[] - */ - public function getItems() - { - return $this->_items; - } - - /** - * Set the list of items - * - * @param SagepayItem[] $items - */ - public function setItems(array $items) - { - $this->_items = $items; - } - - /** - * Add the item to basket - * - * @param SagepayItem $item - */ - public function addItem(SagepayItem $item) - { - $this->_items[] = $item; - } - - /** - * Get delivery net amount - * - * @return type - */ - public function getDeliveryNetAmount() - { - return $this->_deliveryNetAmount; - } - - /** - * Set delivery net amount - * - * @param float $deliveryNetAmount - */ - public function setDeliveryNetAmount($deliveryNetAmount) - { - $this->_deliveryNetAmount = $deliveryNetAmount; - } - - /** - * Get delivery tax - * - * @return float - */ - public function getDeliveryTaxAmount() - { - return $this->_deliveryTaxAmount; - } - - /** - * Set delivery tax - * - * @param float $deliveryTaxAmount - */ - public function setDeliveryTaxAmount($deliveryTaxAmount) - { - $this->_deliveryTaxAmount = $deliveryTaxAmount; - } - - /** - * Get delivery gross amount - * - * @return float - */ - public function getDeliveryGrossAmount() - { - return $this->_deliveryNetAmount + $this->_deliveryTaxAmount; - } - - /** - * Get list of discounts - * - * @return array - */ - public function getDiscounts() - { - return $this->_discounts; - } - - /** - * Set list of discounts - * - * @param array $discounts - */ - public function setDiscounts(array $discounts) - { - $this->_discounts = $discounts; - } - - /** - * Get shipping ID - * - * @return string - */ - public function getShipId() - { - return $this->_shipId; - } - - /** - * Set shipping ID - * - * @param string $shipId - */ - public function setShipId($shipId) - { - $this->_shipId = $shipId; - } - - /** - * Get shipping method - * - * @return string - */ - public function getShippingMethod() - { - return $this->_shippingMethod; - } - - /** - * Set shipping method - * - * @param string $shippingMethod - */ - public function setShippingMethod($shippingMethod) - { - $this->_shippingMethod = $shippingMethod; - } - - /** - * Get shipping fax number - * - * @return string - */ - public function getShippingFaxNo() - { - return $this->_shippingFaxNo; - } - - /** - * Set shipping fax number - * - * @param string $shippingFaxNo - */ - public function setShippingFaxNo($shippingFaxNo) - { - $this->_shippingFaxNo = $shippingFaxNo; - } - - /** - * Get tour operator structure - * - * @return array - */ - public function getTourOperator() - { - return $this->_tourOperator; - } - - /** - * Set tour operator structure - * - * @param array $tourOperator - */ - public function setTourOperator(array $tourOperator) - { - $this->_tourOperator = $tourOperator; - } - - /** - * Get car rental structure - * - * @return array - */ - public function getCarRental() - { - return $this->_carRental; - } - - /** - * Set car rental structure - * - * @param array $carRental - */ - public function setCarRental(array $carRental) - { - $this->_carRental = $carRental; - } - - /** - * Get hotel structure - * - * @return array - */ - public function getHotel() - { - return $this->_hotel; - } - - /** - * Set hotel structure - * - * @param array $hotel - */ - public function setHotel(array $hotel) - { - $this->_hotel = $hotel; - } - - /** - * Get cruise structure - * - * @return array - */ - public function getCruise() - { - return $this->_cruise; - } - - /** - * Set cruise structure - * - * @param array $cruise - */ - public function setCruise(array $cruise) - { - $this->_cruise = $cruise; - } - - /** - * Get airline structure - * - * @return array - */ - public function getAirline() - { - return $this->_airline; - } - - /** - * Set airline structure - * - * @param array $airline - */ - public function setAirline(array $airline) - { - $this->_airline = $airline; - } - - /** - * get dinerCustomerRef - * - * @return string - */ - public function getDinerCustomerRef() - { - return $this->_dinerCustomerRef; - } - - /** - * Set dinerCustomerRef - * - * @param string $dinerCustomerRef - */ - public function setDinerCustomerRef($dinerCustomerRef) - { - $this->_dinerCustomerRef = $dinerCustomerRef; - } - - /** - * Get the total amount of basket - * - * @return float - */ - public function getAmount() - { - $amount = $this->getDeliveryGrossAmount(); - foreach ($this->_items as $item) - { - $amount += $item->getTotalGrossAmount(); - } - return $amount; - } - - /** - * Return xml structured or serialized string depends on $asXml - * - * @param bool $asXml - * - * @return string - */ - public function exportAsXml($asXml = true) - { - if ($asXml) - { - return $this->_toXml(); - } - return $this->_serialize(); - } - - /** - * Export as string with Sagepay specific format - * - * @return type - */ - private function _serialize() - { - $values = array(count($this->_items)); - foreach ($this->_items as $item) - { - $itemArr = $item->asArray(); - foreach ($this->_struct as $key) - { - $values[] = is_null($itemArr[$key]) ? '---' : $itemArr[$key]; - } - } - if ($this->getDeliveryGrossAmount() > 0) - { - $values[0]++; - $values[] = 'Delivery'; - $values[] = 1; - $values[] = number_format($this->getDeliveryNetAmount(), 2); - $values[] = number_format($this->getDeliveryTaxAmount(), 2); - $values[] = number_format($this->getDeliveryGrossAmount(), 2); - $values[] = number_format($this->getDeliveryGrossAmount(), 2); - } - - return implode(':', $values); - } - - /** - * Export Basket as XML - * - * @return string - */ - private function _toXml() - { - $dom = new DOMDocument(); - $dom->formatOutput = false; - $dom->loadXML(''); - foreach ($this->_exportFields as $name) - { - $value = NULL; - $getter = "get" . ucfirst($name); - if (method_exists($this, $getter)) - { - $value = $this->$getter(); - } - - if (empty($value)) - { - continue; - } - - $node = $this->_createDomNode($dom, $value, $name); - if ($node instanceof DOMNode) - { - $dom->documentElement->appendChild($node); - } - else if ($node instanceof DOMNodeList) - { - for ($i = 0, $n = $node->length; $i < $n; $i++) - { - $child = $node->item(0); - if ($child instanceof DOMNode) - { - $dom->documentElement->appendChild($child); - } - } - } - } - return $dom->saveXML($dom->documentElement); - } - - /** - * Create a DOMNode from property - * - * @param DOMDocument $dom - * @param string $name - * @param mixed $value - * @return DOMNode|DOMNodeList - */ - private function _createDomNode($dom, $value, $name = null) - { - if ($value instanceof SagepayItem) - { - return $value->asDomElement($dom); - } - else if ($name === null) - { - return $dom->createElement($value); - } - else if (is_string($value) || is_int($value)) - { - return $dom->createElement($name, trim($value)); - } - else if (is_float($value)) - { - return $dom->createElement($name, number_format($value, 2, '.', '')); - } - else if (is_array($value)) - { - if (count($value) === 0) - { - return null; - } - $base = $dom->createElement($name); - if (array_keys($value) !== range(0, count($value) - 1)) - { - // For Associative Array - foreach ($value as $_key => $_val) - { - $node = $this->_createDomNode($dom, $_val, $_key); - $base->appendChild($node); - } - return $base; - } - else - { - foreach ($value as $_val) - { - $node = $this->_createDomNode($dom, $_val); - $base->appendChild($node); - } - return $base->childNodes; - } - } - } - -} +_id = (string) time(); + } + + /** + * Get basket ID + * + * @return string + */ + public function getId() + { + return $this->_id; + } + + /** + * Set basket ID + * + * @param string $id + */ + public function setId($id) + { + if (SagepayValid::digit($id)) + { + $this->_id = (string) $id; + } + } + + /** + * Get description of goods purchased is displayed on the Sage Pay Form payment page as the customer enters their card details. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Set basket description + * + * @param string $description + */ + public function setDescription($description) + { + $this->_description = substr($description, 0, 100); + } + + /** + * Get ID of the seller if using a phone payment. + * + * @return string + */ + public function getAgentId() + { + return $this->_agentId; + } + + /** + * Set ID of the seller if using a phone payment. + * + * @param string $agentId + */ + public function setAgentId($agentId) + { + if (SagepayValid::regex($agentId, '/^[a-zA-Z0-9\ ]{1,16}$/')) + { + $this->_agentId = $agentId; + } + } + + /** + * Get list of items + * + * @return SagepayItem[] + */ + public function getItems() + { + return $this->_items; + } + + /** + * Set the list of items + * + * @param SagepayItem[] $items + */ + public function setItems(array $items) + { + $this->_items = $items; + } + + /** + * Add the item to basket + * + * @param SagepayItem $item + */ + public function addItem(SagepayItem $item) + { + $this->_items[] = $item; + } + + /** + * Get delivery net amount + * + * @return type + */ + public function getDeliveryNetAmount() + { + return $this->_deliveryNetAmount; + } + + /** + * Set delivery net amount + * + * @param float $deliveryNetAmount + */ + public function setDeliveryNetAmount($deliveryNetAmount) + { + $this->_deliveryNetAmount = $deliveryNetAmount; + } + + /** + * Get delivery tax + * + * @return float + */ + public function getDeliveryTaxAmount() + { + return $this->_deliveryTaxAmount; + } + + /** + * Set delivery tax + * + * @param float $deliveryTaxAmount + */ + public function setDeliveryTaxAmount($deliveryTaxAmount) + { + $this->_deliveryTaxAmount = $deliveryTaxAmount; + } + + /** + * Get delivery gross amount + * + * @return float + */ + public function getDeliveryGrossAmount() + { + return $this->_deliveryNetAmount + $this->_deliveryTaxAmount; + } + + /** + * Get list of discounts + * + * @return array + */ + public function getDiscounts() + { + return $this->_discounts; + } + + /** + * Set list of discounts + * + * @param array $discounts + */ + public function setDiscounts(array $discounts) + { + $this->_discounts = $discounts; + } + + /** + * Get shipping ID + * + * @return string + */ + public function getShipId() + { + return $this->_shipId; + } + + /** + * Set shipping ID + * + * @param string $shipId + */ + public function setShipId($shipId) + { + $this->_shipId = $shipId; + } + + /** + * Get shipping method + * + * @return string + */ + public function getShippingMethod() + { + return $this->_shippingMethod; + } + + /** + * Set shipping method + * + * @param string $shippingMethod + */ + public function setShippingMethod($shippingMethod) + { + $this->_shippingMethod = $shippingMethod; + } + + /** + * Get shipping fax number + * + * @return string + */ + public function getShippingFaxNo() + { + return $this->_shippingFaxNo; + } + + /** + * Set shipping fax number + * + * @param string $shippingFaxNo + */ + public function setShippingFaxNo($shippingFaxNo) + { + $this->_shippingFaxNo = $shippingFaxNo; + } + + /** + * Get tour operator structure + * + * @return array + */ + public function getTourOperator() + { + return $this->_tourOperator; + } + + /** + * Set tour operator structure + * + * @param array $tourOperator + */ + public function setTourOperator(array $tourOperator) + { + $this->_tourOperator = $tourOperator; + } + + /** + * Get car rental structure + * + * @return array + */ + public function getCarRental() + { + return $this->_carRental; + } + + /** + * Set car rental structure + * + * @param array $carRental + */ + public function setCarRental(array $carRental) + { + $this->_carRental = $carRental; + } + + /** + * Get hotel structure + * + * @return array + */ + public function getHotel() + { + return $this->_hotel; + } + + /** + * Set hotel structure + * + * @param array $hotel + */ + public function setHotel(array $hotel) + { + $this->_hotel = $hotel; + } + + /** + * Get cruise structure + * + * @return array + */ + public function getCruise() + { + return $this->_cruise; + } + + /** + * Set cruise structure + * + * @param array $cruise + */ + public function setCruise(array $cruise) + { + $this->_cruise = $cruise; + } + + /** + * Get airline structure + * + * @return array + */ + public function getAirline() + { + return $this->_airline; + } + + /** + * Set airline structure + * + * @param array $airline + */ + public function setAirline(array $airline) + { + $this->_airline = $airline; + } + + /** + * get dinerCustomerRef + * + * @return string + */ + public function getDinerCustomerRef() + { + return $this->_dinerCustomerRef; + } + + /** + * Set dinerCustomerRef + * + * @param string $dinerCustomerRef + */ + public function setDinerCustomerRef($dinerCustomerRef) + { + $this->_dinerCustomerRef = $dinerCustomerRef; + } + + /** + * Get the total amount of basket + * + * @return float + */ + public function getAmount() + { + $amount = $this->getDeliveryGrossAmount(); + foreach ($this->_items as $item) + { + $amount += $item->getTotalGrossAmount(); + } + return $amount; + } + + /** + * Return xml structured or serialized string depends on $asXml + * + * @param bool $asXml + * + * @return string + */ + public function exportAsXml($asXml = true) + { + if ($asXml) + { + return $this->_toXml(); + } + return $this->_serialize(); + } + + /** + * Export as string with Sagepay specific format + * + * @return type + */ + private function _serialize() + { + $values = array(count($this->_items)); + foreach ($this->_items as $item) + { + $itemArr = $item->asArray(); + foreach ($this->_struct as $key) + { + $values[] = is_null($itemArr[$key]) ? '---' : $itemArr[$key]; + } + } + if ($this->getDeliveryGrossAmount() > 0) + { + $values[0]++; + $values[] = 'Delivery'; + $values[] = 1; + $values[] = number_format($this->getDeliveryNetAmount(), 2); + $values[] = number_format($this->getDeliveryTaxAmount(), 2); + $values[] = number_format($this->getDeliveryGrossAmount(), 2); + $values[] = number_format($this->getDeliveryGrossAmount(), 2); + } + + return implode(':', $values); + } + + /** + * Export Basket as XML + * + * @return string + */ + private function _toXml() + { + $dom = new DOMDocument(); + $dom->formatOutput = false; + $dom->loadXML(''); + foreach ($this->_exportFields as $name) + { + $value = NULL; + $getter = "get" . ucfirst($name); + if (method_exists($this, $getter)) + { + $value = $this->$getter(); + } + + if (empty($value)) + { + continue; + } + + $node = $this->_createDomNode($dom, $value, $name); + if ($node instanceof DOMNode) + { + $dom->documentElement->appendChild($node); + } + else if ($node instanceof DOMNodeList) + { + for ($i = 0, $n = $node->length; $i < $n; $i++) + { + $child = $node->item(0); + if ($child instanceof DOMNode) + { + $dom->documentElement->appendChild($child); + } + } + } + } + return $dom->saveXML($dom->documentElement); + } + + /** + * Create a DOMNode from property + * + * @param DOMDocument $dom + * @param string $name + * @param mixed $value + * @return DOMNode|DOMNodeList + */ + private function _createDomNode($dom, $value, $name = null) + { + if ($value instanceof SagepayItem) + { + return $value->asDomElement($dom); + } + else if ($name === null) + { + return $dom->createElement($value); + } + else if (is_string($value) || is_int($value)) + { + return $dom->createElement($name, trim($value)); + } + else if (is_float($value)) + { + return $dom->createElement($name, number_format($value, 2, '.', '')); + } + else if (is_array($value)) + { + if (count($value) === 0) + { + return null; + } + $base = $dom->createElement($name); + if (array_keys($value) !== range(0, count($value) - 1)) + { + // For Associative Array + foreach ($value as $_key => $_val) + { + $node = $this->_createDomNode($dom, $_val, $_key); + $base->appendChild($node); + } + return $base; + } + else + { + foreach ($value as $_val) + { + $node = $this->_createDomNode($dom, $_val); + $base->appendChild($node); + } + return $base->childNodes; + } + } + } + +} diff --git a/src/Sagepay/classes/card_details.php b/src/Sagepay/classes/card_details.php index 85cdc3e..75598fb 100755 --- a/src/Sagepay/classes/card_details.php +++ b/src/Sagepay/classes/card_details.php @@ -1,152 +1,152 @@ - array( - array('notEmpty'), - array('creditCard'), - ), - 'cardHolder' => array( - array('notEmpty'), - array('maxLength', array(20)), - array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\\\\\/&\.\']*$/")), - ), - 'startDate' => array( - array('regex', array("/^([0-9]{4})*$/")), - ), - 'expiryDate' => array( - array('notEmpty'), - array('regex', array("/^([0-9]{4})*$/")), - ), - 'cv2' => array( - array('notEmpty'), - ), - ); - - /** - * Reading data from inaccessible properties. - * - * @param string $name - * @return string - */ - public function __get($name) - { - $privateName = "_" . $name; - if (property_exists($this, $privateName)) - { - return $this->$privateName; - } - return null; - } - - /** - * Writing data to inaccessible properties - * - * @param string $name - * @param string $value - */ - public function __set($name, $value) - { - $privateName = "_" . $name; - if (property_exists($this, $privateName)) - { - $this->$privateName = $value; - } - } - - - /** - * Validates values using validation rules and return the result - * - * @return array - */ - public function validate() - { - if ($this->cardType == 'AMEX') - { - $this->rules['cv2'][] = array('exactLength', array(3, 4)); - } - else - { - $this->rules['cv2'][] = array('exactLength', array(3)); - } - - $errors = array(); - foreach ($this->rules as $key => $rule) - { - $propertyValue = $this->$key; - $validator = new SagepayValidator($propertyValue, $rule); - if (!$validator->isValid()) - { - $errors[$key] = $validator->getErrors(); - } - } - return $errors; - } - -} + array( + array('notEmpty'), + array('creditCard'), + ), + 'cardHolder' => array( + array('notEmpty'), + array('maxLength', array(20)), + array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\\\\\/&\.\']*$/")), + ), + 'startDate' => array( + array('regex', array("/^([0-9]{4})*$/")), + ), + 'expiryDate' => array( + array('notEmpty'), + array('regex', array("/^([0-9]{4})*$/")), + ), + 'cv2' => array( + array('notEmpty'), + ), + ); + + /** + * Reading data from inaccessible properties. + * + * @param string $name + * @return string + */ + public function __get($name) + { + $privateName = "_" . $name; + if (property_exists($this, $privateName)) + { + return $this->$privateName; + } + return null; + } + + /** + * Writing data to inaccessible properties + * + * @param string $name + * @param string $value + */ + public function __set($name, $value) + { + $privateName = "_" . $name; + if (property_exists($this, $privateName)) + { + $this->$privateName = $value; + } + } + + + /** + * Validates values using validation rules and return the result + * + * @return array + */ + public function validate() + { + if ($this->cardType == 'AMEX') + { + $this->rules['cv2'][] = array('exactLength', array(3, 4)); + } + else + { + $this->rules['cv2'][] = array('exactLength', array(3)); + } + + $errors = array(); + foreach ($this->rules as $key => $rule) + { + $propertyValue = $this->$key; + $validator = new SagepayValidator($propertyValue, $rule); + if (!$validator->isValid()) + { + $errors[$key] = $validator->getErrors(); + } + } + return $errors; + } + +} diff --git a/src/Sagepay/classes/customer.php b/src/Sagepay/classes/customer.php index 7dd401e..da15c24 100755 --- a/src/Sagepay/classes/customer.php +++ b/src/Sagepay/classes/customer.php @@ -1,285 +1,285 @@ - array( - array('exactLength', array(1)), - ), - 'customerBirth' => array( - array('exactLength', array(10)), - array('regex', array("/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}*$/")), - ), - 'customerWorkPhone' => array( - array('minLength', array(11)), - array('maxLength', array(19)), - array('regex', array("/^[0-9\-a-zA-Z+\s()]*$/")), - ), - 'customerMobilePhone' => array( - array('minLength', array(11)), - array('maxLength', array(19)), - array('regex', array("/^[0-9\-a-zA-Z+\s()]*$/")), - ), - 'previousCust' => array( - array('exactLength', array(1)), - array('regex', array("/^[01]$/")), - ), - 'timeOnFile' => array( - array('maxLength', array(16)), - array('regex', array("/^[0-9]+$/")), - ), - 'customerId' => array( - array('regex', array("/^[A-Za-z0-9]$/")), - ), - - ); - - /** - * Get middle initial of the customer - * - * @return string - */ - public function getCustomerMiddleInitial() - { - return $this->_customerMiddleInitial; - } - - /** - * Set middle initial of the customer - * - * @param string $customerMiddleInitial - */ - public function setCustomerMiddleInitial($customerMiddleInitial) - { - $this->_customerMiddleInitial = $customerMiddleInitial; - } - - /** - * Get date of birth of the customer - * - * @return string - */ - public function getCustomerBirth() - { - return $this->_customerBirth; - } - - /** - * Set date of birth of the customer - * - * @param string $customerBirth - */ - public function setCustomerBirth($customerBirth) - { - $this->_customerBirth = $customerBirth; - } - - /** - * Get work phone number of the customer. - * - * @return string - */ - public function getCustomerWorkPhone() - { - return $this->_customerWorkPhone; - } - - /** - * Set work phone number of the customer. - * - * @param string $customerWorkPhone - */ - public function setCustomerWorkPhone($customerWorkPhone) - { - $this->_customerWorkPhone = $customerWorkPhone; - } - - /** - * Get mobile number of the customer - * - * @return string - */ - public function getCustomerMobilePhone() - { - return $this->_customerMobilePhone; - } - - /** - * Set mobile number of the customer - * - * @param string $customerMobilePhone - */ - public function setCustomerMobilePhone($customerMobilePhone) - { - $this->_customerMobilePhone = $customerMobilePhone; - } - - /** - * Get is a previous customer - * - * @return int - */ - public function getPreviousCust() - { - return $this->_previousCust; - } - - /** - * Set is a previous customer - * - * @param int $previousCust - */ - public function setPreviousCust($previousCust) - { - $this->_previousCust = intval(!!$previousCust); - } - - /** - * Get the number of days since the card was first seen. - * - * @return int - */ - public function getTimeOnFile() - { - return $this->_timeOnFile; - } - - /** - * Set the number of days since the card was first seen. - * - * @param int $timeOnFile - */ - public function setTimeOnFile($timeOnFile) - { - $this->_timeOnFile = intval($timeOnFile); - } - - /** - * Get customer ID - * - * @return string - */ - public function getCustomerId() - { - return $this->_customerId; - } - - /** - * Set customer ID - * - * @param string $customerId - */ - public function setCustomerId($customerId) - { - $this->_customerId = $customerId; - } - - /** - * Export customer details as XML string - * - * @return string XML with customer details - */ - public function export() - { - $dom = new DOMDocument(); - $dom->loadXML(""); - foreach ($this->_exportFields as $field) - { - $value = NULL; - $getter = 'get' . ucfirst($field); - if (method_exists($this, $getter)) - { - $value = $this->$getter(); - } - - if (empty($value)) - { - continue; - } - $node = $dom->createElement($field, $value); - $dom->documentElement->appendChild($node); - } - return $dom->saveXML($dom->documentElement); - } - -} - + array( + array('exactLength', array(1)), + ), + 'customerBirth' => array( + array('exactLength', array(10)), + array('regex', array("/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}*$/")), + ), + 'customerWorkPhone' => array( + array('minLength', array(11)), + array('maxLength', array(19)), + array('regex', array("/^[0-9\-a-zA-Z+\s()]*$/")), + ), + 'customerMobilePhone' => array( + array('minLength', array(11)), + array('maxLength', array(19)), + array('regex', array("/^[0-9\-a-zA-Z+\s()]*$/")), + ), + 'previousCust' => array( + array('exactLength', array(1)), + array('regex', array("/^[01]$/")), + ), + 'timeOnFile' => array( + array('maxLength', array(16)), + array('regex', array("/^[0-9]+$/")), + ), + 'customerId' => array( + array('regex', array("/^[A-Za-z0-9]$/")), + ), + + ); + + /** + * Get middle initial of the customer + * + * @return string + */ + public function getCustomerMiddleInitial() + { + return $this->_customerMiddleInitial; + } + + /** + * Set middle initial of the customer + * + * @param string $customerMiddleInitial + */ + public function setCustomerMiddleInitial($customerMiddleInitial) + { + $this->_customerMiddleInitial = $customerMiddleInitial; + } + + /** + * Get date of birth of the customer + * + * @return string + */ + public function getCustomerBirth() + { + return $this->_customerBirth; + } + + /** + * Set date of birth of the customer + * + * @param string $customerBirth + */ + public function setCustomerBirth($customerBirth) + { + $this->_customerBirth = $customerBirth; + } + + /** + * Get work phone number of the customer. + * + * @return string + */ + public function getCustomerWorkPhone() + { + return $this->_customerWorkPhone; + } + + /** + * Set work phone number of the customer. + * + * @param string $customerWorkPhone + */ + public function setCustomerWorkPhone($customerWorkPhone) + { + $this->_customerWorkPhone = $customerWorkPhone; + } + + /** + * Get mobile number of the customer + * + * @return string + */ + public function getCustomerMobilePhone() + { + return $this->_customerMobilePhone; + } + + /** + * Set mobile number of the customer + * + * @param string $customerMobilePhone + */ + public function setCustomerMobilePhone($customerMobilePhone) + { + $this->_customerMobilePhone = $customerMobilePhone; + } + + /** + * Get is a previous customer + * + * @return int + */ + public function getPreviousCust() + { + return $this->_previousCust; + } + + /** + * Set is a previous customer + * + * @param int $previousCust + */ + public function setPreviousCust($previousCust) + { + $this->_previousCust = intval(!!$previousCust); + } + + /** + * Get the number of days since the card was first seen. + * + * @return int + */ + public function getTimeOnFile() + { + return $this->_timeOnFile; + } + + /** + * Set the number of days since the card was first seen. + * + * @param int $timeOnFile + */ + public function setTimeOnFile($timeOnFile) + { + $this->_timeOnFile = intval($timeOnFile); + } + + /** + * Get customer ID + * + * @return string + */ + public function getCustomerId() + { + return $this->_customerId; + } + + /** + * Set customer ID + * + * @param string $customerId + */ + public function setCustomerId($customerId) + { + $this->_customerId = $customerId; + } + + /** + * Export customer details as XML string + * + * @return string XML with customer details + */ + public function export() + { + $dom = new DOMDocument(); + $dom->loadXML(""); + foreach ($this->_exportFields as $field) + { + $value = NULL; + $getter = 'get' . ucfirst($field); + if (method_exists($this, $getter)) + { + $value = $this->$getter(); + } + + if (empty($value)) + { + continue; + } + $node = $dom->createElement($field, $value); + $dom->documentElement->appendChild($node); + } + return $dom->saveXML($dom->documentElement); + } + +} + diff --git a/src/Sagepay/classes/customer_details.php b/src/Sagepay/classes/customer_details.php index 97b41fa..2ebd9d1 100755 --- a/src/Sagepay/classes/customer_details.php +++ b/src/Sagepay/classes/customer_details.php @@ -1,251 +1,251 @@ - array( - array('notEmpty'), - array('maxLength', array(20)), - array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\\\\\/&\.\']*$/")), - ), - 'lastname' => array( - array('notEmpty'), - array('maxLength', array(20)), - array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\\\\\/&\.\']*$/")), - ), - 'address1' => array( - array('notEmpty'), - array('maxLength', array(100)), - array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\+\'\\\\\/&:,\.\-()]*$/")), - ), - 'address2' => array( - array('maxLength', array(100)), - array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\+\'\\\\\/&:,\.\-()]*$/")), - ), - 'email' => array( - array('maxLength', array(255)), - array('email'), - ), - 'phone' => array( - array('maxLength', array(20)), - array('regex', array("/^[0-9\-a-zA-Z+\s()]*$/")), - ), - 'city' => array( - array('notEmpty'), - array('maxLength', array(40)), - array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\+\'\\\\\/&:,\.\-()]*$/")), - ), - 'postcode' => array( - array('maxLength', array(10)), - array('regex', array("/^[a-zA-Z0-9\s-]*$/")), - ), - 'country' => array( - array('notEmpty'), - array('maxLength', array(2)), - array('regex', array("/^[A-Z]{2}$/")), - ), - 'state' => array( - array('maxLength', array(2)), - array('regex', array("/^([A-Z]{2})*$/")), - ), - ); - - - /** - * Reading data from inaccessible properties. - * - * @param string $name - * @return string - */ - public function __get($name) - { - $privateName = "_" . $name; - if (property_exists($this, $privateName)) - { - return $this->$privateName; - } - return null; - } - - /** - * Writing data to inaccessible properties - * - * @param string $name - * @param string $value - */ - public function __set($name, $value) - { - $privateName = "_" . $name; - if (property_exists($this, $privateName)) - { - $this->$privateName = $value; - } - } - - /** - * Constructor for SagepayCustomerDetails - */ - public function __construct() - { - $this->rules['state'][] = array(array($this, 'validUsa')); - $this->rules['postcode'][] = array(array($this, 'notEmptyZipCodeUK')); - } - - /** - * Get default postcode if the address supplied didn't have one - * - * @param string $default The default value to use when not found or empty - * - * @return string - */ - public function getPostCode($default = '') - { - if (empty($this->_postcode)) - { - $this->_postcode = $default; - } - return $this->_postcode; - } - - /** - * Validates values using validation rules and return the result - * - * @return string[] - */ - public function validate() - { - $errors = array(); - foreach ($this->rules as $key => $rule) - { - $propertyValue = $this->$key; - $validator = new SagepayValidator($propertyValue, $rule); - if (!$validator->isValid()) - { - $errors[$key] = $validator->getErrors(); - } - } - return $errors; - } - - /** - * Validate State Code for US only - * Validate State Code for other country not US - * - * @param string $value - * - * @return boolean - */ - public function validUsa($value) - { - if ($this->_country == 'US') - { - return SagepayValid::notEmpty($value); - } - else - { - return SagepayValid::equals($value, ""); - } - } - - /** - * Validate Zip Code for UK only - * - * @param string $value - * - * @return boolean - */ - public function notEmptyZipCodeUK($value) - { - if ($this->_country == 'GB') - { - return SagepayValid::notEmpty($value); - } - return true; - } - -} + array( + array('notEmpty'), + array('maxLength', array(20)), + array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\\\\\/&\.\']*$/")), + ), + 'lastname' => array( + array('notEmpty'), + array('maxLength', array(20)), + array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\\\\\/&\.\']*$/")), + ), + 'address1' => array( + array('notEmpty'), + array('maxLength', array(100)), + array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\+\'\\\\\/&:,\.\-()]*$/")), + ), + 'address2' => array( + array('maxLength', array(100)), + array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\+\'\\\\\/&:,\.\-()]*$/")), + ), + 'email' => array( + array('maxLength', array(255)), + array('email'), + ), + 'phone' => array( + array('maxLength', array(20)), + array('regex', array("/^[0-9\-a-zA-Z+\s()]*$/")), + ), + 'city' => array( + array('notEmpty'), + array('maxLength', array(40)), + array('regex', array("/^[a-zA-Z\xC0-\xFF0-9\s\+\'\\\\\/&:,\.\-()]*$/")), + ), + 'postcode' => array( + array('maxLength', array(10)), + array('regex', array("/^[a-zA-Z0-9\s-]*$/")), + ), + 'country' => array( + array('notEmpty'), + array('maxLength', array(2)), + array('regex', array("/^[A-Z]{2}$/")), + ), + 'state' => array( + array('maxLength', array(2)), + array('regex', array("/^([A-Z]{2})*$/")), + ), + ); + + + /** + * Reading data from inaccessible properties. + * + * @param string $name + * @return string + */ + public function __get($name) + { + $privateName = "_" . $name; + if (property_exists($this, $privateName)) + { + return $this->$privateName; + } + return null; + } + + /** + * Writing data to inaccessible properties + * + * @param string $name + * @param string $value + */ + public function __set($name, $value) + { + $privateName = "_" . $name; + if (property_exists($this, $privateName)) + { + $this->$privateName = $value; + } + } + + /** + * Constructor for SagepayCustomerDetails + */ + public function __construct() + { + $this->rules['state'][] = array(array($this, 'validUsa')); + $this->rules['postcode'][] = array(array($this, 'notEmptyZipCodeUK')); + } + + /** + * Get default postcode if the address supplied didn't have one + * + * @param string $default The default value to use when not found or empty + * + * @return string + */ + public function getPostCode($default = '') + { + if (empty($this->_postcode)) + { + $this->_postcode = $default; + } + return $this->_postcode; + } + + /** + * Validates values using validation rules and return the result + * + * @return string[] + */ + public function validate() + { + $errors = array(); + foreach ($this->rules as $key => $rule) + { + $propertyValue = $this->$key; + $validator = new SagepayValidator($propertyValue, $rule); + if (!$validator->isValid()) + { + $errors[$key] = $validator->getErrors(); + } + } + return $errors; + } + + /** + * Validate State Code for US only + * Validate State Code for other country not US + * + * @param string $value + * + * @return boolean + */ + public function validUsa($value) + { + if ($this->_country == 'US') + { + return SagepayValid::notEmpty($value); + } + else + { + return SagepayValid::equals($value, ""); + } + } + + /** + * Validate Zip Code for UK only + * + * @param string $value + * + * @return boolean + */ + public function notEmptyZipCodeUK($value) + { + if ($this->_country == 'GB') + { + return SagepayValid::notEmpty($value); + } + return true; + } + +} diff --git a/src/Sagepay/classes/direct_api.php b/src/Sagepay/classes/direct_api.php index 824e71c..fb12853 100755 --- a/src/Sagepay/classes/direct_api.php +++ b/src/Sagepay/classes/direct_api.php @@ -1,127 +1,127 @@ -_vpsDirectUrl = $config->getPurchaseUrl('direct'); - $this->mandatory = array( - 'VPSProtocol', - 'TxType', - 'Vendor', - 'VendorTxCode', - 'Amount', - 'Currency', - 'Description', - 'BillingSurname', - 'BillingFirstnames', - 'BillingAddress1', - 'BillingCity', - 'BillingPostCode', - 'BillingCountry', - 'DeliverySurname', - 'DeliveryFirstnames', - 'DeliveryAddress1', - 'DeliveryCity', - 'DeliveryPostCode', - 'DeliveryCountry', - ); - } - - /** - * Generate values for payment. - * Ensure that post data is setted to request with SagepayAbstractApi::setData() - * - * @see SagepayAbstractApi::createRequest() - * @return array The response from Sage Pay - */ - public function createRequest() - { - $this->data = SagepayCommon::encryptedOrder($this); - $this->addConfiguredValues(); - $this->checkMandatoryFields(); - - $ttl = $this->config->getRequestTimeout(); - $caCert = $this->config->getCaCertPath(); - return SagepayCommon::requestPost($this->_vpsDirectUrl, $this->data, $ttl, $caCert); - } - - /** - * Set integrationMethod - * - * @param string $integrationMethod - */ - public function setIntegrationMethod($integrationMethod) - { - if (in_array($integrationMethod, array(SAGEPAY_DIRECT, SAGEPAY_PAYPAL, SAGEPAY_TOKEN))) - { - $this->integrationMethod = $integrationMethod; - } - } - - /** - * @see SagepayAbstractApi::getQueryData() - * @return null - */ - public function getQueryData() - { - return null; - } - - /** - * Get vpsDirectUrl - * - * @return string - */ - public function getVpsDirectUrl() - { - return $this->_vpsDirectUrl; - } - - /** - * Set vpsDirectUrl - * - * @uses SagepayValid::url Validate URL field - * @param string $vpsDirectUrl - */ - public function setVpsDirectUrl($vpsDirectUrl) - { - if (SagepayValid::url($vpsDirectUrl)) - { - $this->_vpsDirectUrl = $vpsDirectUrl; - } - } - - -} - +_vpsDirectUrl = $config->getPurchaseUrl('direct'); + $this->mandatory = array( + 'VPSProtocol', + 'TxType', + 'Vendor', + 'VendorTxCode', + 'Amount', + 'Currency', + 'Description', + 'BillingSurname', + 'BillingFirstnames', + 'BillingAddress1', + 'BillingCity', + 'BillingPostCode', + 'BillingCountry', + 'DeliverySurname', + 'DeliveryFirstnames', + 'DeliveryAddress1', + 'DeliveryCity', + 'DeliveryPostCode', + 'DeliveryCountry', + ); + } + + /** + * Generate values for payment. + * Ensure that post data is setted to request with SagepayAbstractApi::setData() + * + * @see SagepayAbstractApi::createRequest() + * @return array The response from Sage Pay + */ + public function createRequest() + { + $this->data = SagepayCommon::encryptedOrder($this); + $this->addConfiguredValues(); + $this->checkMandatoryFields(); + + $ttl = $this->config->getRequestTimeout(); + $caCert = $this->config->getCaCertPath(); + return SagepayCommon::requestPost($this->_vpsDirectUrl, $this->data, $ttl, $caCert); + } + + /** + * Set integrationMethod + * + * @param string $integrationMethod + */ + public function setIntegrationMethod($integrationMethod) + { + if (in_array($integrationMethod, array(SAGEPAY_DIRECT, SAGEPAY_PAYPAL, SAGEPAY_TOKEN))) + { + $this->integrationMethod = $integrationMethod; + } + } + + /** + * @see SagepayAbstractApi::getQueryData() + * @return null + */ + public function getQueryData() + { + return null; + } + + /** + * Get vpsDirectUrl + * + * @return string + */ + public function getVpsDirectUrl() + { + return $this->_vpsDirectUrl; + } + + /** + * Set vpsDirectUrl + * + * @uses SagepayValid::url Validate URL field + * @param string $vpsDirectUrl + */ + public function setVpsDirectUrl($vpsDirectUrl) + { + if (SagepayValid::url($vpsDirectUrl)) + { + $this->_vpsDirectUrl = $vpsDirectUrl; + } + } + + +} + diff --git a/src/Sagepay/classes/form_api.php b/src/Sagepay/classes/form_api.php index 29f223c..383decb 100755 --- a/src/Sagepay/classes/form_api.php +++ b/src/Sagepay/classes/form_api.php @@ -1,78 +1,78 @@ -mandatory = array( - 'VendorTxCode', - 'Amount', - 'Currency', - 'Description', - 'SuccessURL', - 'FailureURL', - 'BillingSurname', - 'BillingFirstnames', - 'BillingAddress1', - 'BillingCity', - 'BillingPostCode', - 'BillingCountry', - 'DeliverySurname', - 'DeliveryFirstnames', - 'DeliveryAddress1', - 'DeliveryCity', - 'DeliveryPostCode', - 'DeliveryCountry', - ); - } - - /** - * Return urlencoded string based on data - * - * @uses SagepayUtil::arrayToQueryString - * @return string - */ - public function getQueryData() - { - // Replace after implemeting right View content - return SagepayUtil::arrayToQueryString($this->data); - } - - /** - * Generate values for payment. - * Ensure that post data is setted to request with SagepayAbstractApi::setData() - * - * @see SagepayAbstractApi::createRequest() - * @uses SagepayCommon::encryptedOrder - * @return array The response from Sage Pay - */ - public function createRequest() - { - $this->addConfiguredValues(); - return SagepayCommon::encryptedOrder($this); - } - -} - +mandatory = array( + 'VendorTxCode', + 'Amount', + 'Currency', + 'Description', + 'SuccessURL', + 'FailureURL', + 'BillingSurname', + 'BillingFirstnames', + 'BillingAddress1', + 'BillingCity', + 'BillingPostCode', + 'BillingCountry', + 'DeliverySurname', + 'DeliveryFirstnames', + 'DeliveryAddress1', + 'DeliveryCity', + 'DeliveryPostCode', + 'DeliveryCountry', + ); + } + + /** + * Return urlencoded string based on data + * + * @uses SagepayUtil::arrayToQueryString + * @return string + */ + public function getQueryData() + { + // Replace after implemeting right View content + return SagepayUtil::arrayToQueryString($this->data); + } + + /** + * Generate values for payment. + * Ensure that post data is setted to request with SagepayAbstractApi::setData() + * + * @see SagepayAbstractApi::createRequest() + * @uses SagepayCommon::encryptedOrder + * @return array The response from Sage Pay + */ + public function createRequest() + { + $this->addConfiguredValues(); + return SagepayCommon::encryptedOrder($this); + } + +} + diff --git a/src/Sagepay/classes/item.php b/src/Sagepay/classes/item.php index 5c0ca15..4392f73 100755 --- a/src/Sagepay/classes/item.php +++ b/src/Sagepay/classes/item.php @@ -1,644 +1,644 @@ -_description; - } - - /** - * Set description - * - * @param string $description - */ - public function setDescription($description) - { - $this->_description = $description; - } - - /** - * Get unique product identifier code - * - * @return string - */ - public function getProductSku() - { - return $this->_productSku; - } - - /** - * Set unique product identifier code - * - * @param string $productSku - */ - public function setProductSku($productSku) - { - $this->_productSku = $productSku; - } - - /** - * Get product code - * - * @return string - */ - public function getProductCode() - { - return $this->_productCode; - } - - /** - * Set product code - * - * @param string $productCode - */ - public function setProductCode($productCode) - { - $this->_productCode = $productCode; - } - - /** - * Get quantity of the item ordered - * - * @return integer - */ - public function getQuantity() - { - return $this->_quantity; - } - - /** - * Set quantity of the item ordered - * - * @param integer $quantity - */ - public function setQuantity($quantity) - { - $this->_quantity = intval($quantity); - } - - /** - * Get cost of the item before tax - * - * @return float - */ - public function getUnitNetAmount() - { - return $this->_unitNetAmount; - } - - /** - * Set cost of the item before tax - * - * @param float $unitNetAmount - */ - public function setUnitNetAmount($unitNetAmount) - { - $this->_unitNetAmount = floatval($unitNetAmount); - } - - /** - * Get amount of tax on the item - * - * @return float - */ - public function getUnitTaxAmount() - { - return $this->_unitTaxAmount; - } - - /** - * Set amount of tax on the item - * - * @param float $unitTaxAmount - */ - public function setUnitTaxAmount($unitTaxAmount) - { - $this->_unitTaxAmount = floatval($unitTaxAmount); - } - - /** - * Get total cost of the item with tax - * - * @return float - */ - public function getUnitGrossAmount() - { - return $this->_unitNetAmount + $this->_unitTaxAmount; - } - - /** - * Get total cost of the line including quantity and tax - * - * @return float - */ - public function getTotalGrossAmount() - { - return $this->getUnitGrossAmount() * $this->getQuantity(); - } - - /** - * Get first name of the recipient of this item - * - * @return string - */ - public function getRecipientFName() - { - return $this->_recipientFName; - } - - /** - * Set first name of the recipient of this item - * - * @param string $recipientFName - */ - public function setRecipientFName($recipientFName) - { - $this->_recipientFName = $recipientFName; - } - - /** - * Get last name of the recipient of this item - * - * @return string - */ - public function getRecipientLName() - { - return $this->_recipientLName; - } - - /** - * Set last name of the recipient of this item - * - * @param string $recipientLName - */ - public function setRecipientLName($recipientLName) - { - $this->_recipientLName = $recipientLName; - } - - /** - * Get middle initial of the recipient of this item - * - * @return string - */ - public function getRecipientMName() - { - return $this->_recipientMName; - } - - /** - * Set middle initial of the recipient of this item - * - * @param string $recipientMName - */ - public function setRecipientMName($recipientMName) - { - $this->_recipientMName = $recipientMName; - } - - /** - * Get salutation of the recipient of this item - * - * @return string - */ - public function getRecipientSal() - { - return $this->_recipientSal; - } - - /** - * Set salutation of the recipient of this item - * - * @param string $recipientSal - */ - public function setRecipientSal($recipientSal) - { - $this->_recipientSal = $recipientSal; - } - - /** - * Get email of the recipient of this item - * - * @return string - */ - public function getRecipientEmail() - { - return $this->_recipientEmail; - } - - /** - * Set email of the recipient of this item - * - * @param string $recipientEmail - */ - public function setRecipientEmail($recipientEmail) - { - $this->_recipientEmail = $recipientEmail; - } - - /** - * Get phone number of the recipient of this item - * - * @return string - */ - public function getRecipientPhone() - { - return $this->_recipientPhone; - } - - /** - * Set phone number of the recipient of this item - * - * @param string $recipientPhone - */ - public function setRecipientPhone($recipientPhone) - { - $this->_recipientPhone = $recipientPhone; - } - - /** - * Get first address line of the recipient of this item - * - * @return string - */ - public function getRecipientAdd1() - { - return $this->_recipientAdd1; - } - - /** - * Set first address line of the recipient of this item - * - * @param string $recipientAdd1 - */ - public function setRecipientAdd1($recipientAdd1) - { - $this->_recipientAdd1 = $recipientAdd1; - } - - /** - * Get second address line of the recipient of this item - * - * @return string - */ - public function getRecipientAdd2() - { - return $this->_recipientAdd2; - } - - /** - * Set second address line of the recipient of this item - * - * @param string $recipientAdd2 - */ - public function setRecipientAdd2($recipientAdd2) - { - $this->_recipientAdd2 = $recipientAdd2; - } - - /** - * Get city of the recipient of this item - * - * @return string - */ - public function getRecipientCity() - { - return $this->_recipientCity; - } - - /** - * Set city of the recipient of this item - * - * @param string $recipientCity - */ - public function setRecipientCity($recipientCity) - { - $this->_recipientCity = $recipientCity; - } - - /** - * Get code for the state of the recipient of this item - * - * @return string - */ - public function getRecipientState() - { - return $this->_recipientState; - } - - /** - * Set code for the state of the recipient of this item - * - * @param string $recipientState - */ - public function setRecipientState($recipientState) - { - $this->_recipientState = $recipientState; - } - - /** - * Get country code of the recipient of this item - * - * @return string - */ - public function getRecipientCountry() - { - return $this->_recipientCountry; - } - - /** - * Set country code of the recipient of this item - * - * @param string $recipientCountry - */ - public function setRecipientCountry($recipientCountry) - { - $this->_recipientCountry = $recipientCountry; - } - - /** - * Get postcode of the recipient of this item - * - * @return string - */ - public function getRecipientPostCode() - { - return $this->_recipientPostCode; - } - - /** - * Set postcode of the recipient of this item - * - * @param string $recipientPostCode - */ - public function setRecipientPostCode($recipientPostCode) - { - $this->_recipientPostCode = $recipientPostCode; - } - - /** - * Get shipping item number - * - * @return string - */ - public function getItemShipNo() - { - return $this->_itemShipNo; - } - - /** - * Set shipping item number - * - * @param string $itemShipNo - */ - public function setItemShipNo($itemShipNo) - { - $this->_itemShipNo = $itemShipNo; - } - - /** - * Get gift message associated with this item - * - * @return string - */ - public function getItemGiftMsg() - { - return $this->_itemGiftMsg; - } - - /** - * Set gift message associated with this item - * - * @param string $itemGiftMsg - */ - public function setItemGiftMsg($itemGiftMsg) - { - $this->_itemGiftMsg = $itemGiftMsg; - } - - /** - * Create a DOMNode from property - * - * @param DOMDocument $basket - * - * @return DOMNode - */ - public function asDomElement(DOMDocument $basket) - { - $item = $basket->createElement('item'); - $props = get_class_vars('SagepayItem'); - foreach ($props as $name => $value) - { - $name = substr($name, 1); - if (substr($name, 0, 9) === 'recipient') - { - continue; - } - $getter = "get" . strtoupper($name); - $value = $this->$getter(); - - $node = null; - if (is_string($value) || is_int($value)) - { - $node = $basket->createElement($name, trim($value)); - } - else if (is_float($value)) - { - $node = $basket->createElement($name, number_format($value, 2, '.', '')); - } - if ($node !== null) - { - $item->appendChild($node); - } - } - return $item; - } - - /** - * Return a array of the item properties - * - * @return array - */ - public function asArray() - { - return array( - 'item' => $this->getDescription(), - 'quantity' => $this->getQuantity(), - 'value' => $this->getUnitNetAmount(), - 'tax' => $this->getUnitTaxAmount(), - 'itemTotal' => $this->getUnitGrossAmount(), - 'lineTotal' => $this->getTotalGrossAmount() - ); - } - -} +_description; + } + + /** + * Set description + * + * @param string $description + */ + public function setDescription($description) + { + $this->_description = $description; + } + + /** + * Get unique product identifier code + * + * @return string + */ + public function getProductSku() + { + return $this->_productSku; + } + + /** + * Set unique product identifier code + * + * @param string $productSku + */ + public function setProductSku($productSku) + { + $this->_productSku = $productSku; + } + + /** + * Get product code + * + * @return string + */ + public function getProductCode() + { + return $this->_productCode; + } + + /** + * Set product code + * + * @param string $productCode + */ + public function setProductCode($productCode) + { + $this->_productCode = $productCode; + } + + /** + * Get quantity of the item ordered + * + * @return integer + */ + public function getQuantity() + { + return $this->_quantity; + } + + /** + * Set quantity of the item ordered + * + * @param integer $quantity + */ + public function setQuantity($quantity) + { + $this->_quantity = intval($quantity); + } + + /** + * Get cost of the item before tax + * + * @return float + */ + public function getUnitNetAmount() + { + return $this->_unitNetAmount; + } + + /** + * Set cost of the item before tax + * + * @param float $unitNetAmount + */ + public function setUnitNetAmount($unitNetAmount) + { + $this->_unitNetAmount = floatval($unitNetAmount); + } + + /** + * Get amount of tax on the item + * + * @return float + */ + public function getUnitTaxAmount() + { + return $this->_unitTaxAmount; + } + + /** + * Set amount of tax on the item + * + * @param float $unitTaxAmount + */ + public function setUnitTaxAmount($unitTaxAmount) + { + $this->_unitTaxAmount = floatval($unitTaxAmount); + } + + /** + * Get total cost of the item with tax + * + * @return float + */ + public function getUnitGrossAmount() + { + return $this->_unitNetAmount + $this->_unitTaxAmount; + } + + /** + * Get total cost of the line including quantity and tax + * + * @return float + */ + public function getTotalGrossAmount() + { + return $this->getUnitGrossAmount() * $this->getQuantity(); + } + + /** + * Get first name of the recipient of this item + * + * @return string + */ + public function getRecipientFName() + { + return $this->_recipientFName; + } + + /** + * Set first name of the recipient of this item + * + * @param string $recipientFName + */ + public function setRecipientFName($recipientFName) + { + $this->_recipientFName = $recipientFName; + } + + /** + * Get last name of the recipient of this item + * + * @return string + */ + public function getRecipientLName() + { + return $this->_recipientLName; + } + + /** + * Set last name of the recipient of this item + * + * @param string $recipientLName + */ + public function setRecipientLName($recipientLName) + { + $this->_recipientLName = $recipientLName; + } + + /** + * Get middle initial of the recipient of this item + * + * @return string + */ + public function getRecipientMName() + { + return $this->_recipientMName; + } + + /** + * Set middle initial of the recipient of this item + * + * @param string $recipientMName + */ + public function setRecipientMName($recipientMName) + { + $this->_recipientMName = $recipientMName; + } + + /** + * Get salutation of the recipient of this item + * + * @return string + */ + public function getRecipientSal() + { + return $this->_recipientSal; + } + + /** + * Set salutation of the recipient of this item + * + * @param string $recipientSal + */ + public function setRecipientSal($recipientSal) + { + $this->_recipientSal = $recipientSal; + } + + /** + * Get email of the recipient of this item + * + * @return string + */ + public function getRecipientEmail() + { + return $this->_recipientEmail; + } + + /** + * Set email of the recipient of this item + * + * @param string $recipientEmail + */ + public function setRecipientEmail($recipientEmail) + { + $this->_recipientEmail = $recipientEmail; + } + + /** + * Get phone number of the recipient of this item + * + * @return string + */ + public function getRecipientPhone() + { + return $this->_recipientPhone; + } + + /** + * Set phone number of the recipient of this item + * + * @param string $recipientPhone + */ + public function setRecipientPhone($recipientPhone) + { + $this->_recipientPhone = $recipientPhone; + } + + /** + * Get first address line of the recipient of this item + * + * @return string + */ + public function getRecipientAdd1() + { + return $this->_recipientAdd1; + } + + /** + * Set first address line of the recipient of this item + * + * @param string $recipientAdd1 + */ + public function setRecipientAdd1($recipientAdd1) + { + $this->_recipientAdd1 = $recipientAdd1; + } + + /** + * Get second address line of the recipient of this item + * + * @return string + */ + public function getRecipientAdd2() + { + return $this->_recipientAdd2; + } + + /** + * Set second address line of the recipient of this item + * + * @param string $recipientAdd2 + */ + public function setRecipientAdd2($recipientAdd2) + { + $this->_recipientAdd2 = $recipientAdd2; + } + + /** + * Get city of the recipient of this item + * + * @return string + */ + public function getRecipientCity() + { + return $this->_recipientCity; + } + + /** + * Set city of the recipient of this item + * + * @param string $recipientCity + */ + public function setRecipientCity($recipientCity) + { + $this->_recipientCity = $recipientCity; + } + + /** + * Get code for the state of the recipient of this item + * + * @return string + */ + public function getRecipientState() + { + return $this->_recipientState; + } + + /** + * Set code for the state of the recipient of this item + * + * @param string $recipientState + */ + public function setRecipientState($recipientState) + { + $this->_recipientState = $recipientState; + } + + /** + * Get country code of the recipient of this item + * + * @return string + */ + public function getRecipientCountry() + { + return $this->_recipientCountry; + } + + /** + * Set country code of the recipient of this item + * + * @param string $recipientCountry + */ + public function setRecipientCountry($recipientCountry) + { + $this->_recipientCountry = $recipientCountry; + } + + /** + * Get postcode of the recipient of this item + * + * @return string + */ + public function getRecipientPostCode() + { + return $this->_recipientPostCode; + } + + /** + * Set postcode of the recipient of this item + * + * @param string $recipientPostCode + */ + public function setRecipientPostCode($recipientPostCode) + { + $this->_recipientPostCode = $recipientPostCode; + } + + /** + * Get shipping item number + * + * @return string + */ + public function getItemShipNo() + { + return $this->_itemShipNo; + } + + /** + * Set shipping item number + * + * @param string $itemShipNo + */ + public function setItemShipNo($itemShipNo) + { + $this->_itemShipNo = $itemShipNo; + } + + /** + * Get gift message associated with this item + * + * @return string + */ + public function getItemGiftMsg() + { + return $this->_itemGiftMsg; + } + + /** + * Set gift message associated with this item + * + * @param string $itemGiftMsg + */ + public function setItemGiftMsg($itemGiftMsg) + { + $this->_itemGiftMsg = $itemGiftMsg; + } + + /** + * Create a DOMNode from property + * + * @param DOMDocument $basket + * + * @return DOMNode + */ + public function asDomElement(DOMDocument $basket) + { + $item = $basket->createElement('item'); + $props = get_class_vars('SagepayItem'); + foreach ($props as $name => $value) + { + $name = substr($name, 1); + if (substr($name, 0, 9) === 'recipient') + { + continue; + } + $getter = "get" . strtoupper($name); + $value = $this->$getter(); + + $node = null; + if (is_string($value) || is_int($value)) + { + $node = $basket->createElement($name, trim($value)); + } + else if (is_float($value)) + { + $node = $basket->createElement($name, number_format($value, 2, '.', '')); + } + if ($node !== null) + { + $item->appendChild($node); + } + } + return $item; + } + + /** + * Return a array of the item properties + * + * @return array + */ + public function asArray() + { + return array( + 'item' => $this->getDescription(), + 'quantity' => $this->getQuantity(), + 'value' => $this->getUnitNetAmount(), + 'tax' => $this->getUnitTaxAmount(), + 'itemTotal' => $this->getUnitGrossAmount(), + 'lineTotal' => $this->getTotalGrossAmount() + ); + } + +} diff --git a/src/Sagepay/classes/server_api.php b/src/Sagepay/classes/server_api.php index 3206928..9d3fbc3 100755 --- a/src/Sagepay/classes/server_api.php +++ b/src/Sagepay/classes/server_api.php @@ -1,115 +1,115 @@ -_vpsServerUrl = $config->getPurchaseUrl('server'); - $this->mandatory = array( - 'VPSProtocol', - 'TxType', - 'Vendor', - 'VendorTxCode', - 'Amount', - 'Currency', - 'Description', - 'NotificationURL', - 'BillingSurname', - 'BillingFirstnames', - 'BillingAddress1', - 'BillingCity', - 'BillingPostCode', - 'BillingCountry', - 'DeliverySurname', - 'DeliveryFirstnames', - 'DeliveryAddress1', - 'DeliveryCity', - 'DeliveryPostCode', - 'DeliveryCountry', - 'StoreToken' - ); - } - - /** - * Generate values for payment. - * Ensure that post data is setted to request with SagepayAbstractApi::setData() - * - * @see SagepayAbstractApi::createRequest() - * @return array The response from Sage Pay - */ - public function createRequest() - { - $this->data = SagepayCommon::encryptedOrder($this); - $this->addConfiguredValues(); - $this->checkMandatoryFields(); - - $ttl = $this->config->getRequestTimeout(); - $caCert = $this->config->getCaCertPath(); - return SagepayCommon::requestPost($this->_vpsServerUrl, $this->data, $ttl, $caCert); - } - - /** - * @see SagepayAbstractApi::getQueryData() - * @return null - */ - public function getQueryData() - { - return null; - } - - /** - * Get vpsServerUrl - * - * @return type - */ - public function getVpsServerUrl() - { - return $this->_vpsServerUrl; - } - - /** - * Set vpsServerUrl - * - * @uses SagepayValid::url Validate URL field - * @param type $vpsServerUrl - */ - public function setVpsServerUrl($vpsServerUrl) - { - if (SagepayValid::url($vpsServerUrl)) - { - $this->_vpsServerUrl = $vpsServerUrl; - } - } - -} - +_vpsServerUrl = $config->getPurchaseUrl('server'); + $this->mandatory = array( + 'VPSProtocol', + 'TxType', + 'Vendor', + 'VendorTxCode', + 'Amount', + 'Currency', + 'Description', + 'NotificationURL', + 'BillingSurname', + 'BillingFirstnames', + 'BillingAddress1', + 'BillingCity', + 'BillingPostCode', + 'BillingCountry', + 'DeliverySurname', + 'DeliveryFirstnames', + 'DeliveryAddress1', + 'DeliveryCity', + 'DeliveryPostCode', + 'DeliveryCountry', + 'StoreToken' + ); + } + + /** + * Generate values for payment. + * Ensure that post data is setted to request with SagepayAbstractApi::setData() + * + * @see SagepayAbstractApi::createRequest() + * @return array The response from Sage Pay + */ + public function createRequest() + { + $this->data = SagepayCommon::encryptedOrder($this); + $this->addConfiguredValues(); + $this->checkMandatoryFields(); + + $ttl = $this->config->getRequestTimeout(); + $caCert = $this->config->getCaCertPath(); + return SagepayCommon::requestPost($this->_vpsServerUrl, $this->data, $ttl, $caCert); + } + + /** + * @see SagepayAbstractApi::getQueryData() + * @return null + */ + public function getQueryData() + { + return null; + } + + /** + * Get vpsServerUrl + * + * @return type + */ + public function getVpsServerUrl() + { + return $this->_vpsServerUrl; + } + + /** + * Set vpsServerUrl + * + * @uses SagepayValid::url Validate URL field + * @param type $vpsServerUrl + */ + public function setVpsServerUrl($vpsServerUrl) + { + if (SagepayValid::url($vpsServerUrl)) + { + $this->_vpsServerUrl = $vpsServerUrl; + } + } + +} + diff --git a/src/Sagepay/classes/settings.php b/src/Sagepay/classes/settings.php index b8ba195..ac9adb5 100755 --- a/src/Sagepay/classes/settings.php +++ b/src/Sagepay/classes/settings.php @@ -1,1435 +1,1435 @@ -Mandatory.
- * Specify the correct server environment to connect(test or live).
- * Default: test - * - * @var string - */ - private $_env = SAGEPAY_ENV_TEST; - - /** - * Mandatory.
- * SagePay Protocol Version used for payment
- * Default: 3.00 - * - * @var float - */ - private $_protocolVersion = 3.00; - - /** - * Mandatory. - * Vendor name provided by Sagepay service - * - * @var string - */ - private $_vendorName = ''; - - /** - * Vendor email - * Set this to the mail address which will receive order confirmations and failures - * - * @var string - */ - private $_vendorEmail = ''; - - /** - * Use this to pass data you wish to be displayed against the transaction in MySagePay. - * - * @var string - */ - private $_vendorData = ''; - - /** - * Mandatory. - * Set this to indicate the currency in which you wish to trade. - * Should be ISO 4217 Valid - * - * @link http://en.wikipedia.org/wiki/ISO_4217 - * @var string - */ - private $_currency = 'GBP'; - - /** - * Mandatory. - * Usually PAYMENT. This can be DEFERRED or AUTHENTICATE - * if your Sage Pay account supports those payment types - * - * @var string - */ - private $_txType = SAGEPAY_TXN_PAYMENT; - - /** - * The URL of a vendor's server can be overwritten - * which will send a custom notificationURL and failure/successURL to the Sage Pay gateway - * - * @var string[] - */ - private $_siteFqdn = array( - 'test' => '', - 'live' => '', - ); - - /** - * If you are a Sage Pay Partner and wish to flag the transactions with your unique partner id, - * it should be set here - * - * @var string - */ - private $_partnerId = ''; - - /** - * Apply Address Verification Status / Card Verification Value - * 0 = If AVS/CV2 enabled then check them. If rules apply, use rules (default). - * 1 = Force AVS/CV2 checks even if not enabled for the account. If rules apply, use rules. - * 2 = Force NO AVS/CV2 checks even if enabled on account. - * 3 = Force AVS/CV2 checks even if not enabled for the account but DON'T apply any rules. - * - * @var int - */ - private $_applyAvsCv2 = 0; - - /** - * Apply 3D-Secure - * 0 = If 3D-Secure checks are possible and rules allow, perform the checks and apply the authorisation rules. (default) - * 1 = Force 3D-Secure checks for this transaction if possible and apply rules for authorisation. - * 2 = Do not perform 3D-Secure checks for this transaction and always authorise. - * 3 = Force 3D-Secure checks for this transaction if possible but ALWAYS obtain an auth code, irrespective of rule base. - * - * @var int - */ - private $_apply3dSecure = 0; - - /** - * For charities registered for Gift Aid, - * set to 1 to display the Gift Aid check - * box on the payment pages, or else 0 - * (Server & Form protocols only) - * - * @var int - */ - private $_allowGiftAid = 0; - - /** - * Use this to send surcharge xml and override the default values set for your account. - * - * @var array - */ - private $_surcharges = array(); - - /** - * If you are a dealing with financial transfers then offer the option to collect - * details about the recipient - * - * @var boolean - */ - private $_collectRecipientDetails = false; - - // FORM Protocol only - - /** - * Set this value to the AES encryption password assigned to you by Sage Pay - * - * @var array - */ - private $_formPassword = array( - 'test' => '0123456789abcdef', - 'live' => '0123456789abcdef', - ); - - /** - * Set this value for success page redirect for FORM Protocol - * - * @var string - */ - private $_formSuccessUrl = ''; - - /** - * Set this value for failure page redirect for FORM Protocol - * - * @var string - */ - private $_formFailureUrl = ''; - - /** - * Send email - * 0 = Do not send either customer or vendor e-mails, - * 1 = Send customer and vendor e-mails if address(es) are provided(DEFAULT). - * 2 = Send Vendor Email but not Customer Email. If you do not supply this field, 1 is assumed and e-mails are sent if addresses are provided. - * - * @var int - */ - private $_sendEmail = 1; - - /** - * Contents of email message. - * You can specify any custom message to send to your customers in their confirmation e-mail here - * The field can contain HTML if you wish, and be different for each order. - * - * @var string - */ - private $_emailMessage = 'Thanks for your order'; - - // DIRECT & SERVER Protocol only - - /** - * This value will be used to set the BillingAgreement field in the registration POST - * A default is value of 0 is used if this parameter is not included in this properties file - * - * @var int - */ - private $_billingAgreement = 0; - - // DIRECT Protocol only - - /** - * Tell the SagePay System which merchant account to use. - * If omitted the system will use E, then M, then C by default. - * E = Use the e-commerce merchant account (default). - * M = Use the mail - * C = Use the continuous authority merchant account (if present). - * - * @var string - */ - private $_accountType; - - /** - * Any 7 character salt for the local customer password database used by the kit - * - * @var string - */ - private $_customerPasswordSalt = ''; - - /** - * Set this to false to use colon delimited format for the basket instead of XML - * - * @var boolean - */ - private $_basketAsXmlDisable = false; - - /** - * Server profile used by default - * - * @var string - */ - private $_serverProfile = SAGEPAY_SERVER_PROFILE_NORMAL; - - /** - * Set this value for notification url called by Sagepay System for SERVER Protocol - * - * @var string - */ - private $_serverNotificationUrl = ''; - - /** - * Set this value for callback url called by PayPal - * - * @var string - */ - private $_paypalCallbackUrl = ''; - - /** - * List of Purchase URLs used for Registration Transaction - * - * @var array - */ - private $_purchaseUrls = array( - 'test' => array( - 'form' => SAGEPAY_FORM_SERVER_TEST, - 'server' => SAGEPAY_SERVER_SERVER_TEST, - 'direct' => SAGEPAY_DIRECT_SERVER_TEST, - 'direct3d' => SAGEPAY_DIRECT_SERVER_3D_SECURE_CALLBACK_TEST, - 'paypal' => SAGEPAY_PAYPAL_COMPLETION_TEST, - ), - 'live' => array( - 'form' => SAGEPAY_FORM_SERVER_LIVE, - 'server' => SAGEPAY_SERVER_SERVER_LIVE, - 'direct' => SAGEPAY_DIRECT_SERVER_TEST, - 'direct3d' => SAGEPAY_DIRECT_SERVER_3D_SECURE_CALLBACK_LIVE, - 'paypal' => SAGEPAY_PAYPAL_COMPLETION_LIVE, - ) - ); - - /** - * List of Shared URLs used for admin panel actions - * - * @var array - */ - private $_sharedUrls = array( - 'test' => array( - 'repeat' => SAGEPAY_SHARED_REPEAT_TRANSACTION_TEST, - 'abort' => SAGEPAY_SHARED_ABORT_TRANSACTION_TEST, - 'release' => SAGEPAY_SHARED_RELEASE_TRANSACTION_TEST, - 'refund' => SAGEPAY_SHARED_REFUND_TRANSACTION_TEST, - 'void' => SAGEPAY_SHARED_VOID_TRANSACTION_TEST, - 'authorise' => SAGEPAY_SHARED_AUTHORISE_TRANSACTION_TEST, - 'cancel' => SAGEPAY_SHARED_CANCEL_TRANSACTION_TEST, - ), - 'live' => array( - 'repeat' => SAGEPAY_SHARED_REPEAT_TRANSACTION_LIVE, - 'abort' => SAGEPAY_SHARED_ABORT_TRANSACTION_LIVE, - 'release' => SAGEPAY_SHARED_RELEASE_TRANSACTION_LIVE, - 'refund' => SAGEPAY_SHARED_REFUND_TRANSACTION_LIVE, - 'void' => SAGEPAY_SHARED_VOID_TRANSACTION_LIVE, - 'authorise' => SAGEPAY_SHARED_AUTHORISE_TRANSACTION_LIVE, - 'cancel' => SAGEPAY_SHARED_CANCEL_TRANSACTION_LIVE, - ) - ); - - /** - * List of Token URLs used for store/remove token - * - * @var array - */ - private $_tokenUrls = array( - 'test' => array( - 'register-server' => SAGEPAY_SERVER_TOKEN_REGISTER_TEST, - 'register-direct' => SAGEPAY_DIRECT_TOKEN_REGISTER_TEST, - 'remove' => SAGEPAY_TOKEN_REMOVE_TEST, - ), - 'live' => array( - 'register-server' => SAGEPAY_SERVER_TOKEN_REGISTER_LIVE, - 'register-direct' => SAGEPAY_DIRECT_TOKEN_REGISTER_LIVE, - 'remove' => SAGEPAY_TOKEN_REMOVE_LIVE, - ) - ); - - /** - * If it is true, all logs will be stored in debug.log - * - * @var boolean - */ - private $_logError = false; - - /** - * The language the customer sees the payment pages in is determined by the code sent here. - * If this is null then the language default of the shoppers browser will be used. - * - * @var string - */ - private $_language = null; - - /** - * Reference to the website this transaction came from. - * This field is useful if transactions can originate from more than one website. - * - * @var string - */ - private $_website = null; - - /** - * Timeout for POST cURL requests - * - * @var int - */ - private $_requestTimeout = 30; - - /** - * The name of a file holding one or more certificates to verify the peer with. - * - * @var string - */ - private $_caCertPath = ''; - - /** - * Initialize the configuration depends on array or if $config is null, - * then load from file. - * - * @param array $config Well-formed associative array - * @param boolean $loadFileConfig Load configurations from file - */ - private function __construct(array $config, $loadFileConfig) - { - if ($loadFileConfig) - { - $fileConfig = $this->_loadFileConfig(); - $config = array_merge($fileConfig, $config); - } - $this->_applyConfig($config); - } - - /** - * Restrict clone functionality - */ - private function __clone() - { - } - - /** - * Get instance of settings - * - * @param array $config - * @param boolean $loadFileConfig - * @return SagepaySettings - */ - static public function getInstance(array $config = array(), $loadFileConfig = true) - { - if (self::$_instance === null) - { - self::$_instance = new SagepaySettings($config, $loadFileConfig); - } - return self::$_instance; - } - - /** - * Get environment. - * - * @return string Environment - */ - public function getEnv() - { - return $this->_env; - } - - /** - * Set environment - * - * @param string $_env Environment - */ - public function setEnv($env) - { - if (in_array($env, array(SAGEPAY_ENV_TEST, SAGEPAY_ENV_LIVE))) - { - $this->_env = $env; - } - else - { - trigger_error("Invalid Environment value, [test, live] expected, " . $env . " given", E_USER_WARNING); - } - } - - /** - * Get SagePay Protocol Version used for payment - * - * @return float Protocol version - */ - public function getProtocolVersion() - { - return number_format($this->_protocolVersion, 2); - } - - /** - * Set SagePay Protocol Version used for payment - * - * @param float $_protocolVersion Protocol version - */ - public function setProtocolVersion($protocolVersion) - { - if (is_float($protocolVersion)) - { - $this->_protocolVersion = floatval($protocolVersion); - } - else - { - trigger_error("Invalid Protocol Version value, float expected, " . gettype($protocolVersion) . " given", E_USER_WARNING); - } - } - - /** - * Get vendor name provided by Sagepay service - * - * @return string Vendor name - */ - public function getVendorName() - { - return $this->_vendorName; - } - - /** - * Set vendor name provided by Sagepay service - * - * @param string $vendorName Vendor name - */ - public function setVendorName($vendorName) - { - $this->_vendorName = $vendorName; - } - - /** - * Get value of vendor data you wish to be displayed against the transaction in MySagePay. - * - * @return string Vendor data - */ - public function getVendorData() - { - return $this->_vendorData; - } - - /** - * Set value of vendor data you wish to be displayed against the transaction in MySagePay. - * - * @param string $vendorData vendor data - */ - public function setVendorData($vendorData) - { - $this->_vendorData = $vendorData; - } - - /** - * Get currency in which you wish to trade - * - * @return string Currency - */ - public function getCurrency() - { - return $this->_currency; - } - - /** - * Set currency in which you wish to trade - * - * @param string $currency Currency - */ - public function setCurrency($currency) - { - $this->_currency = $currency; - } - - /** - * Get transaction type - * - * @return string Transaction type - */ - public function getTxType() - { - return $this->_txType; - } - - /** - * Set transaction type - * - * @param string $txType Transaction type - */ - public function setTxType($txType) - { - $this->_txType = $txType; - } - - /** - * Get list of URL of a vendor's server - * - * @return array List of siteFqdn - */ - public function getSiteFqdns() - { - return $this->_siteFqdn; - } - - /** - * Set list of URL of a vendor's server - * - * @param array $siteFqdn List of siteFqdn - */ - public function setSiteFqdns(array $siteFqdn) - { - $this->_siteFqdn = $siteFqdn; - } - - /** - * Get unique partner ID - * - * @return string Partner ID - */ - public function getPartnerId() - { - return $this->_partnerId; - } - - /** - * Set unique partner ID - * - * @param string $partnerId Partner ID - */ - public function setPartnerId($partnerId) - { - $this->_partnerId = $partnerId; - } - - /** - * Get value of Address Verification Status / Card Verification Value option - * - * @return int Apply AVS/CV2 validation option - */ - public function getApplyAvsCv2() - { - return $this->_applyAvsCv2; - } - - /** - * Set value of Address Verification Status / Card Verification Value option - * - * @param int $applyAvsCv2 Apply AVS/CV2 validation option - */ - public function setApplyAvsCv2($applyAvsCv2) - { - if (in_array($applyAvsCv2, range(0, 3))) - { - $this->_applyAvsCv2 = $applyAvsCv2; - } - else - { - trigger_error("Invalid Apply AVS/CV2 value, [0, 1, 2, 3] expected, " . $applyAvsCv2 . " given", E_USER_WARNING); - } - } - - /** - * Get value of 3D Secure Verification option - * - * @return int 3D Secure Verification option - */ - public function getApply3dSecure() - { - return $this->_apply3dSecure; - } - - /** - * Set value of 3D Secure Verification option - * - * @param int $apply3dSecure 3D Secure Verification option - */ - public function setApply3dSecure($apply3dSecure) - { - if (in_array($apply3dSecure, range(0, 3))) - { - $this->_apply3dSecure = $apply3dSecure; - } - else - { - trigger_error("Invalid Apply 3D Secure value, [0, 1, 2, 3] expected, " . $apply3dSecure . " given", E_USER_WARNING); - } - } - - /** - * Get value of Allow gift aid option - * - * @return int Allow gift aid option - */ - public function getAllowGiftAid() - { - return $this->_allowGiftAid; - } - - /** - * Set value of Allow gift aid option - * - * @param int $allowGiftAid Allow gift aid option - */ - public function setAllowGiftAid($allowGiftAid) - { - if (in_array($allowGiftAid, range(0, 1))) - { - $this->_allowGiftAid = $allowGiftAid; - } - else - { - trigger_error("Invalid Allow Gift Aid value, [0, 1] expected, " . $allowGiftAid . " given", E_USER_WARNING); - } - } - - /** - * Get List of Surcharges - * - * @return array list of Surcharges - */ - public function getSurcharges() - { - return $this->_surcharges; - } - - /** - * Set list of Surcharges - * - * @param array $surcharges list of Surcharges - */ - public function setSurcharges($surcharges) - { - $this->_surcharges = $surcharges; - } - - /** - * Get value of Collect recipient details option - * - * @return boolean Collect recipient details option - */ - public function getCollectRecipientDetails() - { - return $this->_collectRecipientDetails; - } - - /** - * Set value of Collect recipient details option - * - * @param boolean $collect Collect recipient details option - */ - public function setCollectRecipientDetails($collect) - { - if (is_bool($collect)) - { - $this->_collectRecipientDetails = $collect; - } - else - { - trigger_error("Invalid Collect Recipient Details value, boolean expected, " . gettype($collect) . " given", E_USER_WARNING); - } - } - - /** - * Get list of FORM Protocol encryption password setting - * AES encryption password assigned to you by Sage Pay - * - * @return array list of FORM Protocol encryption password - */ - public function getFormPassword() - { - return $this->_formPassword; - } - - /** - * Set list of FORM Protocol encryption password setting - * AES encryption password assigned to you by Sage Pay - * - * @param array $formPassword list of FORM Protocol encryption password - */ - public function setFormPassword($formPassword) - { - $this->_formPassword = $formPassword; - } - - /** - * Get success page redirect for FORM Protocol - * - * @return string FORM Protocol success URL - */ - public function getFormSuccessUrl() - { - return $this->_formSuccessUrl; - } - - - /** - * Set success page redirect for FORM Protocol - * - * @param string $formSuccessUrl FORM Protocol success URL - */ - public function setFormSuccessUrl($formSuccessUrl) - { - $this->_formSuccessUrl = $formSuccessUrl; - } - - /** - * Get failure page redirect for FORM Protocol - * - * @return string FORM Protocol failure URL - */ - public function getFormFailureUrl() - { - return $this->_formFailureUrl; - } - - /** - * Set failure page redirect for FORM Protocol - * - * @param string $formFailureUrl FORM Protocol failure URL - */ - public function setFormFailureUrl($formFailureUrl) - { - $this->_formFailureUrl = $formFailureUrl; - } - - /** - * Get merchant account type - * - * @return type - */ - public function getAccountType() - { - return $this->_accountType; - } - - /** - * Set merchant account type - * - * @param string $accountType - */ - public function setAccountType($accountType) - { - if (in_array($accountType, array(SAGEPAY_ACCOUNT_ECOMMERCE, SAGEPAY_ACCOUNT_CONTINUOUS, SAGEPAY_ACCOUNT_MAIL))) - { - $this->_accountType = $accountType; - } - else - { - trigger_error("Invalid Account Type value, [E, C, M] expected, '" . $accountType . "' given", E_USER_WARNING); - } - } - - /** - * Get server profile used by default - * - * @return type SERVER Protocol profile - */ - public function getServerProfile() - { - return $this->_serverProfile; - } - - /** - * Set server profile used by default - * - * @param string $serverProfile SERVER Protocol profile - */ - public function setServerProfile($serverProfile) - { - if (in_array($serverProfile, array(SAGEPAY_SERVER_PROFILE_LOW, SAGEPAY_SERVER_PROFILE_NORMAL))) - { - $this->_serverProfile = $serverProfile; - } - else - { - trigger_error("Invalid Server Profile value, [NORMAL, LOW] expected, '" . $serverProfile . "' given", E_USER_WARNING); - } - } - - /** - * Get value for notification url called by Sagepay System for SERVER Protocol - * - * @return string SERVER Protocol Notification URL - */ - public function getServerNotificationUrl() - { - return $this->_serverNotificationUrl; - } - - /** - * Set value for notification url called by Sagepay System for SERVER Protocol - * - * @param string $serverNotificationUrl SERVER Protocol Notification URL - */ - public function setserverNotificationUrl($serverNotificationUrl) - { - $this->_serverNotificationUrl = $serverNotificationUrl; - } - - /** - * Get password salt for the local customer password database used by the kit - * - * @return string Password salt - */ - public function getCustomerPasswordSalt() - { - return $this->_customerPasswordSalt; - } - - /** - * Set password salt for the local customer password database used by the kit - * 7 chars length - * - * @param string $customerPasswordSalt Password salt - */ - public function setCustomerPasswordSalt($customerPasswordSalt) - { - $this->_customerPasswordSalt = substr($customerPasswordSalt, 0, 7); - } - - /** - * Get value of Billing Agreement option - * - * @return int Billing Agreement option - */ - public function getBillingAgreement() - { - return $this->_billingAgreement; - } - - /** - * Set value of Billing Agreement option - * - * @param int $billingAgreement Billing Agreement option - */ - public function setBillingAgreement($billingAgreement) - { - if (in_array($billingAgreement, array(0, 1), true)) - { - $this->_billingAgreement = $billingAgreement; - } - else - { - trigger_error("Invalid Billing Agreement value, [0, 1] expected, " . $billingAgreement . " given", E_USER_WARNING); - } - } - - /** - * Get value of Send e-mail option - * - * @return int Send e-mail option - */ - public function getSendEmail() - { - return $this->_sendEmail; - } - - /** - * Set value of Send e-mail option - * - * @param int $sendEmail Send e-mail option - */ - public function setSendEmail($sendEmail) - { - $this->_sendEmail = $sendEmail; - } - - /** - * Get e-mail message - * - * @return string E-mail message - */ - public function getEmailMessage() - { - return $this->_emailMessage; - } - - /** - * Set e-mail message - * - * @param string $emailMessage E-mail message - */ - public function setEmailMessage($emailMessage) - { - $this->_emailMessage = strip_tags($emailMessage); - } - - /** - * Get value of vendor email - * - * @return string Vendor email - */ - public function getVendorEmail() - { - return $this->_vendorEmail; - } - - /** - * Set value of vendor email - * - * @param string $vendorEmail Vendor email - */ - public function setVendorEmail($vendorEmail) - { - if (SagepayValid::email($vendorEmail)) - { - $this->_vendorEmail = $vendorEmail; - } - else - { - trigger_error("Invalid Vendor Email value, email format expected, '" . $vendorEmail . "' given", E_USER_WARNING); - } - } - - /** - * Get value of Basket as XML seeting - * - * @return boolean Basket as XML - */ - public function basketAsXmlDisabled() - { - return $this->_basketAsXmlDisable; - } - - /** - * Set value of Basket as XML seeting - * - * @param boolean $basketAsXmlDisable Basket as XML - */ - public function setBasketAsXmlDisable($basketAsXmlDisable) - { - if (is_bool($basketAsXmlDisable)) - { - $this->_basketAsXmlDisable = $basketAsXmlDisable; - } - else - { - trigger_error("Invalid Basket as XML value, boolean expected, " . gettype($basketAsXmlDisable) . " given", E_USER_WARNING); - } - } - - /** - * Get value of PayPal Callback URL - * - * @return string PayPal Callback URL - */ - public function getPaypalCallbackUrl() - { - return $this->_paypalCallbackUrl; - } - - /** - * Set value of PayPal Callback URL - * - * @param string $paypalCallbackUrl PayPal Callback URL - */ - public function setPaypalCallbackUrl($paypalCallbackUrl) - { - $this->_paypalCallbackUrl = $paypalCallbackUrl; - } - - /** - * Get list of Registration Service - * - * @return array List of Registration Service - */ - public function getPurchaseUrls() - { - return $this->_purchaseUrls; - } - - /** - * Set list of Registration Services - * - * @param array $purchaseUrls List of Registration Service - */ - public function setPurchaseUrls($purchaseUrls) - { - $this->_purchaseUrls = $this->_mergeEnvironmentUrls($this->_purchaseUrls, $purchaseUrls); - } - - /** - * Get list of Shared Services - * - * @return array List of Shared Services - */ - public function getSharedUrls() - { - return $this->_sharedUrls; - } - - /** - * Set list of Shared Services - * - * @param array $sharedUrls List of Shared Services - */ - public function setSharedUrls($sharedUrls) - { - $this->_sharedUrls = $this->_mergeEnvironmentUrls($this->_sharedUrls, $sharedUrls); - } - - /** - * Get list of Token Services - * - * @return array List of Token Services - */ - public function getTokenUrls() - { - return $this->_tokenUrls; - } - - /** - * Set list of Token Services - * - * @param array $tokenUrls List of Token Services - */ - public function setTokenUrls($tokenUrls) - { - $this->_tokenUrls = $this->_mergeEnvironmentUrls($this->_tokenUrls, $tokenUrls); - } - - /** - * Get Log Error option - * - * @return boolean - */ - public function getLogError() - { - return $this->_logError; - } - - /** - * Set Log Error option - * - * @param boolean $logError - */ - public function setLogError($logError) - { - if (is_bool($logError)) - { - $this->_logError = $logError; - } - else - { - trigger_error("Invalid Log Error, boolean expected, " . gettype($logError) . " given", E_USER_WARNING); - } - } - - /** - * Get language value ISO 639-1 valid - * - * @return type - */ - public function getLanguage() - { - return $this->_language; - } - - /** - * Get language value ISO 639-1 valid - * @link http://en.wikipedia.org/wiki/ISO_639 - * - * @param type $language - */ - public function setLanguage($language) - { - $this->_language = substr($language, 0, 2); - } - - /** - * Get reference to the website this transaction came from. - * - * @return type - */ - public function getWebsite() - { - return $this->_website; - } - - /** - * Set reference to the website this transaction came from. - * - * @param type $website - */ - public function setWebsite($website) - { - if (!empty($website) && SagepayValid::url($website)) - { - $this->_website = $website; - } - else - { - trigger_error("Invalid Website URL value, email format expected, '" . $website . "' given", E_USER_WARNING); - } - } - - /** - * Get timeout for POST cURL requests - * - * @return int - */ - public function getRequestTimeout() - { - return $this->_requestTimeout; - } - - /** - * Set timeout for POST cURL requests - * - * @param int $ttl - */ - public function setRequestTimeout($ttl) - { - if (is_int($ttl)) - { - $this->_requestTimeout = $ttl; - } - else - { - trigger_error("Invalid request timeout value, integer expected, '" . $ttl . "' given", E_USER_WARNING); - } - } - - /** - * Get CACert file path - * - * @return string - */ - public function getCaCertPath() - { - return $this->_caCertPath; - } - - /** - * Set CACert file path - * - * @param string $caCertPath - */ - public function setCaCertPath($caCertPath) - { - $this->_caCertPath = $caCertPath; - } - - /** - * Get value of siteFqdn for specific environment - * - * @param string $env Specific environment - * - * @return string SiteFqdn URL - */ - public function getSiteFqdn($env = '') - { - $env = $this->_validEnvironment($env); - return $this->_siteFqdn[$env]; - } - - /** - * Set value of siteFqdn for specific environment - * - * @param string $siteFqdn SiteFqdn URL - * @param string $env Specific environment - */ - public function setSiteFqdn($siteFqdn, $env = '') - { - $env = $this->_validEnvironment($env); - $this->_siteFqdn[$env] = $siteFqdn; - } - - /** - * Set Encryption password for specific environment - * - * @param string $password Encryption password - * @param string $env Environment name, by default is using current environment value - */ - public function setFormEncryptionPassword($password, $env = '') - { - $env = $this->_validEnvironment($env); - $this->_formPassword[$env] = $password; - } - - - /** - * Get full URL for Form Successes - * - * @param string $env Specific environment - * @return string - */ - public function getFullFormSuccessUrl($env = '') - { - $base = $this->getSiteFqdn($env); - return $base . $this->_formSuccessUrl; - } - - /** - * Get full URL for Form Failures - * - * @param string $env Specific environment - * @return string - */ - public function getFullFormFailureUrl($env = '') - { - $base = $this->getSiteFqdn($env); - return $base . $this->_formFailureUrl; - } - - /** - * Get full URL for Server Notifications - * - * @param string $env Specific environment - * @return string - */ - public function getFullServerNotificationUrl($env = '') - { - $base = $this->getSiteFqdn($env); - return $base . $this->_serverNotificationUrl; - } - - /** - * Get Encryption password for specific environment - * - * @param string $env Environment name, by default is using current environment value - * - * @return string Encryption password - */ - public function getFormEncryptionPassword($env = '') - { - $env = $this->_validEnvironment($env); - return $this->_formPassword[$env]; - } - - /** - * Get value of specific Registration Service - * - * @param string $method Method alias - * @param string $env Environment name, by default is using current environment value - * - * @return string Registration Service URL - */ - public function getPurchaseUrl($method, $env = '') - { - $env = $this->_validEnvironment($env); - if (isset($this->_purchaseUrls[$env][$method])) - { - return $this->_purchaseUrls[$env][$method]; - } - return ''; - } - - /** - * Set value of specific method of Registration Services - * - * @param string $purchaseUrl Registration Service URL - * @param string $method Method alias - * @param string $env Environment name, by default is using current environment value - */ - public function setPurchaseUrl($purchaseUrl, $method, $env = '') - { - $env = $this->_validEnvironment($env); - if (!empty($method) && !empty($purchaseUrl)) - { - $this->_purchaseUrls[$env][$method] = $purchaseUrl; - } - } - - /** - * Get value of specific method of Shared Services - * - * @param string $method Method alias - * @param string $env Environment name, by default is using current environment value - * - * @return string Shared Service URL - */ - public function getSharedUrl($method, $env = '') - { - $env = $this->_validEnvironment($env); - if (isset($this->_sharedUrls[$env][$method])) - { - return $this->_sharedUrls[$env][$method]; - } - return ''; - } - - /** - * Set value of specific method of Shared Services - * - * @param string $sharedUrl Shared Service URL - * @param string $method Method alias - * @param string $env Environment name, by default is using current environment value - */ - public function setSharedUrl($sharedUrl, $method, $env = '') - { - $env = $this->_validEnvironment($env); - if (!empty($method) && !empty($sharedUrl)) - { - $this->_sharedUrls[$env][$method] = $sharedUrl; - } - } - - /** - * Get url for specific token service and environment - * - * @param string $method Method name - * @param string $env Environment name, by default is using current environment value - * - * @return string Token Service URL - */ - public function getTokenUrl($method, $env = '') - { - - $env = $this->_validEnvironment($env); - if (isset($this->_tokenUrls[$env][$method])) - { - return $this->_tokenUrls[$env][$method]; - } - return ''; - } - - /** - * Set url for specific token service and environment - * - * @param string $tokenUrl Token Service URL - * @param string $method Method name - * @param string $env Environment name, by default is using current environment value - */ - public function setTokenUrl($tokenUrl, $method, $env = '') - { - $env = $this->_validEnvironment($env); - if (!empty($method) && !empty($tokenUrl)) - { - $this->_tokenUrls[$env][$method] = $tokenUrl; - } - } - - /** - * Load file configuration and return the $config array - * - * @return array Configuration - */ - private function _loadFileConfig() - { - return include SAGEPAY_SDK_PATH . '/config.php'; - } - - /** - * Insert values of array config into current instance SagepayConfig - * - * @param array $config - */ - private function _applyConfig(array $config) - { - foreach ($config as $key => $val) - { - $prop = 'set' . ucfirst($key); - if (method_exists($this, $prop)) - { - $this->$prop($val); - } - } - } - - /** - * Validate value for environment - * Set up current env if it is missing or is not valid environment - * - * @param string $env Environment - * - * @return string Environment - */ - private function _validEnvironment($env) - { - if (!in_array($env, array(SAGEPAY_ENV_TEST, SAGEPAY_ENV_LIVE))) - { - return $this->_env; - } - return $env; - } - - /** - * Recursive merge of URLs - * - * @param array $oldUrls Old URLs values - * @param array $newUrls New URLs values - * - * @return array - */ - private function _mergeEnvironmentUrls(array $oldUrls, array $newUrls) - { - foreach ($oldUrls as $env => $methods) - { - foreach (array_keys($methods) as $method) - { - if (isset($newUrls[$env][$method]) && !empty($newUrls[$env][$method])) - { - $oldUrls[$env][$method] = $newUrls[$env][$method]; - } - } - } - return $oldUrls; - } - -} +Mandatory.
+ * Specify the correct server environment to connect(test or live).
+ * Default: test + * + * @var string + */ + private $_env = SAGEPAY_ENV_TEST; + + /** + * Mandatory.
+ * SagePay Protocol Version used for payment
+ * Default: 3.00 + * + * @var float + */ + private $_protocolVersion = 3.00; + + /** + * Mandatory. + * Vendor name provided by Sagepay service + * + * @var string + */ + private $_vendorName = ''; + + /** + * Vendor email + * Set this to the mail address which will receive order confirmations and failures + * + * @var string + */ + private $_vendorEmail = ''; + + /** + * Use this to pass data you wish to be displayed against the transaction in MySagePay. + * + * @var string + */ + private $_vendorData = ''; + + /** + * Mandatory. + * Set this to indicate the currency in which you wish to trade. + * Should be ISO 4217 Valid + * + * @link http://en.wikipedia.org/wiki/ISO_4217 + * @var string + */ + private $_currency = 'GBP'; + + /** + * Mandatory. + * Usually PAYMENT. This can be DEFERRED or AUTHENTICATE + * if your Sage Pay account supports those payment types + * + * @var string + */ + private $_txType = SAGEPAY_TXN_PAYMENT; + + /** + * The URL of a vendor's server can be overwritten + * which will send a custom notificationURL and failure/successURL to the Sage Pay gateway + * + * @var string[] + */ + private $_siteFqdn = array( + 'test' => '', + 'live' => '', + ); + + /** + * If you are a Sage Pay Partner and wish to flag the transactions with your unique partner id, + * it should be set here + * + * @var string + */ + private $_partnerId = ''; + + /** + * Apply Address Verification Status / Card Verification Value + * 0 = If AVS/CV2 enabled then check them. If rules apply, use rules (default). + * 1 = Force AVS/CV2 checks even if not enabled for the account. If rules apply, use rules. + * 2 = Force NO AVS/CV2 checks even if enabled on account. + * 3 = Force AVS/CV2 checks even if not enabled for the account but DON'T apply any rules. + * + * @var int + */ + private $_applyAvsCv2 = 0; + + /** + * Apply 3D-Secure + * 0 = If 3D-Secure checks are possible and rules allow, perform the checks and apply the authorisation rules. (default) + * 1 = Force 3D-Secure checks for this transaction if possible and apply rules for authorisation. + * 2 = Do not perform 3D-Secure checks for this transaction and always authorise. + * 3 = Force 3D-Secure checks for this transaction if possible but ALWAYS obtain an auth code, irrespective of rule base. + * + * @var int + */ + private $_apply3dSecure = 0; + + /** + * For charities registered for Gift Aid, + * set to 1 to display the Gift Aid check + * box on the payment pages, or else 0 + * (Server & Form protocols only) + * + * @var int + */ + private $_allowGiftAid = 0; + + /** + * Use this to send surcharge xml and override the default values set for your account. + * + * @var array + */ + private $_surcharges = array(); + + /** + * If you are a dealing with financial transfers then offer the option to collect + * details about the recipient + * + * @var boolean + */ + private $_collectRecipientDetails = false; + + // FORM Protocol only + + /** + * Set this value to the AES encryption password assigned to you by Sage Pay + * + * @var array + */ + private $_formPassword = array( + 'test' => '0123456789abcdef', + 'live' => '0123456789abcdef', + ); + + /** + * Set this value for success page redirect for FORM Protocol + * + * @var string + */ + private $_formSuccessUrl = ''; + + /** + * Set this value for failure page redirect for FORM Protocol + * + * @var string + */ + private $_formFailureUrl = ''; + + /** + * Send email + * 0 = Do not send either customer or vendor e-mails, + * 1 = Send customer and vendor e-mails if address(es) are provided(DEFAULT). + * 2 = Send Vendor Email but not Customer Email. If you do not supply this field, 1 is assumed and e-mails are sent if addresses are provided. + * + * @var int + */ + private $_sendEmail = 1; + + /** + * Contents of email message. + * You can specify any custom message to send to your customers in their confirmation e-mail here + * The field can contain HTML if you wish, and be different for each order. + * + * @var string + */ + private $_emailMessage = 'Thanks for your order'; + + // DIRECT & SERVER Protocol only + + /** + * This value will be used to set the BillingAgreement field in the registration POST + * A default is value of 0 is used if this parameter is not included in this properties file + * + * @var int + */ + private $_billingAgreement = 0; + + // DIRECT Protocol only + + /** + * Tell the SagePay System which merchant account to use. + * If omitted the system will use E, then M, then C by default. + * E = Use the e-commerce merchant account (default). + * M = Use the mail + * C = Use the continuous authority merchant account (if present). + * + * @var string + */ + private $_accountType; + + /** + * Any 7 character salt for the local customer password database used by the kit + * + * @var string + */ + private $_customerPasswordSalt = ''; + + /** + * Set this to false to use colon delimited format for the basket instead of XML + * + * @var boolean + */ + private $_basketAsXmlDisable = false; + + /** + * Server profile used by default + * + * @var string + */ + private $_serverProfile = SAGEPAY_SERVER_PROFILE_NORMAL; + + /** + * Set this value for notification url called by Sagepay System for SERVER Protocol + * + * @var string + */ + private $_serverNotificationUrl = ''; + + /** + * Set this value for callback url called by PayPal + * + * @var string + */ + private $_paypalCallbackUrl = ''; + + /** + * List of Purchase URLs used for Registration Transaction + * + * @var array + */ + private $_purchaseUrls = array( + 'test' => array( + 'form' => SAGEPAY_FORM_SERVER_TEST, + 'server' => SAGEPAY_SERVER_SERVER_TEST, + 'direct' => SAGEPAY_DIRECT_SERVER_TEST, + 'direct3d' => SAGEPAY_DIRECT_SERVER_3D_SECURE_CALLBACK_TEST, + 'paypal' => SAGEPAY_PAYPAL_COMPLETION_TEST, + ), + 'live' => array( + 'form' => SAGEPAY_FORM_SERVER_LIVE, + 'server' => SAGEPAY_SERVER_SERVER_LIVE, + 'direct' => SAGEPAY_DIRECT_SERVER_TEST, + 'direct3d' => SAGEPAY_DIRECT_SERVER_3D_SECURE_CALLBACK_LIVE, + 'paypal' => SAGEPAY_PAYPAL_COMPLETION_LIVE, + ) + ); + + /** + * List of Shared URLs used for admin panel actions + * + * @var array + */ + private $_sharedUrls = array( + 'test' => array( + 'repeat' => SAGEPAY_SHARED_REPEAT_TRANSACTION_TEST, + 'abort' => SAGEPAY_SHARED_ABORT_TRANSACTION_TEST, + 'release' => SAGEPAY_SHARED_RELEASE_TRANSACTION_TEST, + 'refund' => SAGEPAY_SHARED_REFUND_TRANSACTION_TEST, + 'void' => SAGEPAY_SHARED_VOID_TRANSACTION_TEST, + 'authorise' => SAGEPAY_SHARED_AUTHORISE_TRANSACTION_TEST, + 'cancel' => SAGEPAY_SHARED_CANCEL_TRANSACTION_TEST, + ), + 'live' => array( + 'repeat' => SAGEPAY_SHARED_REPEAT_TRANSACTION_LIVE, + 'abort' => SAGEPAY_SHARED_ABORT_TRANSACTION_LIVE, + 'release' => SAGEPAY_SHARED_RELEASE_TRANSACTION_LIVE, + 'refund' => SAGEPAY_SHARED_REFUND_TRANSACTION_LIVE, + 'void' => SAGEPAY_SHARED_VOID_TRANSACTION_LIVE, + 'authorise' => SAGEPAY_SHARED_AUTHORISE_TRANSACTION_LIVE, + 'cancel' => SAGEPAY_SHARED_CANCEL_TRANSACTION_LIVE, + ) + ); + + /** + * List of Token URLs used for store/remove token + * + * @var array + */ + private $_tokenUrls = array( + 'test' => array( + 'register-server' => SAGEPAY_SERVER_TOKEN_REGISTER_TEST, + 'register-direct' => SAGEPAY_DIRECT_TOKEN_REGISTER_TEST, + 'remove' => SAGEPAY_TOKEN_REMOVE_TEST, + ), + 'live' => array( + 'register-server' => SAGEPAY_SERVER_TOKEN_REGISTER_LIVE, + 'register-direct' => SAGEPAY_DIRECT_TOKEN_REGISTER_LIVE, + 'remove' => SAGEPAY_TOKEN_REMOVE_LIVE, + ) + ); + + /** + * If it is true, all logs will be stored in debug.log + * + * @var boolean + */ + private $_logError = false; + + /** + * The language the customer sees the payment pages in is determined by the code sent here. + * If this is null then the language default of the shoppers browser will be used. + * + * @var string + */ + private $_language = null; + + /** + * Reference to the website this transaction came from. + * This field is useful if transactions can originate from more than one website. + * + * @var string + */ + private $_website = null; + + /** + * Timeout for POST cURL requests + * + * @var int + */ + private $_requestTimeout = 30; + + /** + * The name of a file holding one or more certificates to verify the peer with. + * + * @var string + */ + private $_caCertPath = ''; + + /** + * Initialize the configuration depends on array or if $config is null, + * then load from file. + * + * @param array $config Well-formed associative array + * @param boolean $loadFileConfig Load configurations from file + */ + private function __construct(array $config, $loadFileConfig) + { + if ($loadFileConfig) + { + $fileConfig = $this->_loadFileConfig(); + $config = array_merge($fileConfig, $config); + } + $this->_applyConfig($config); + } + + /** + * Restrict clone functionality + */ + private function __clone() + { + } + + /** + * Get instance of settings + * + * @param array $config + * @param boolean $loadFileConfig + * @return SagepaySettings + */ + static public function getInstance(array $config = array(), $loadFileConfig = true) + { + if (self::$_instance === null) + { + self::$_instance = new SagepaySettings($config, $loadFileConfig); + } + return self::$_instance; + } + + /** + * Get environment. + * + * @return string Environment + */ + public function getEnv() + { + return $this->_env; + } + + /** + * Set environment + * + * @param string $_env Environment + */ + public function setEnv($env) + { + if (in_array($env, array(SAGEPAY_ENV_TEST, SAGEPAY_ENV_LIVE))) + { + $this->_env = $env; + } + else + { + trigger_error("Invalid Environment value, [test, live] expected, " . $env . " given", E_USER_WARNING); + } + } + + /** + * Get SagePay Protocol Version used for payment + * + * @return float Protocol version + */ + public function getProtocolVersion() + { + return number_format($this->_protocolVersion, 2); + } + + /** + * Set SagePay Protocol Version used for payment + * + * @param float $_protocolVersion Protocol version + */ + public function setProtocolVersion($protocolVersion) + { + if (is_float($protocolVersion)) + { + $this->_protocolVersion = floatval($protocolVersion); + } + else + { + trigger_error("Invalid Protocol Version value, float expected, " . gettype($protocolVersion) . " given", E_USER_WARNING); + } + } + + /** + * Get vendor name provided by Sagepay service + * + * @return string Vendor name + */ + public function getVendorName() + { + return $this->_vendorName; + } + + /** + * Set vendor name provided by Sagepay service + * + * @param string $vendorName Vendor name + */ + public function setVendorName($vendorName) + { + $this->_vendorName = $vendorName; + } + + /** + * Get value of vendor data you wish to be displayed against the transaction in MySagePay. + * + * @return string Vendor data + */ + public function getVendorData() + { + return $this->_vendorData; + } + + /** + * Set value of vendor data you wish to be displayed against the transaction in MySagePay. + * + * @param string $vendorData vendor data + */ + public function setVendorData($vendorData) + { + $this->_vendorData = $vendorData; + } + + /** + * Get currency in which you wish to trade + * + * @return string Currency + */ + public function getCurrency() + { + return $this->_currency; + } + + /** + * Set currency in which you wish to trade + * + * @param string $currency Currency + */ + public function setCurrency($currency) + { + $this->_currency = $currency; + } + + /** + * Get transaction type + * + * @return string Transaction type + */ + public function getTxType() + { + return $this->_txType; + } + + /** + * Set transaction type + * + * @param string $txType Transaction type + */ + public function setTxType($txType) + { + $this->_txType = $txType; + } + + /** + * Get list of URL of a vendor's server + * + * @return array List of siteFqdn + */ + public function getSiteFqdns() + { + return $this->_siteFqdn; + } + + /** + * Set list of URL of a vendor's server + * + * @param array $siteFqdn List of siteFqdn + */ + public function setSiteFqdns(array $siteFqdn) + { + $this->_siteFqdn = $siteFqdn; + } + + /** + * Get unique partner ID + * + * @return string Partner ID + */ + public function getPartnerId() + { + return $this->_partnerId; + } + + /** + * Set unique partner ID + * + * @param string $partnerId Partner ID + */ + public function setPartnerId($partnerId) + { + $this->_partnerId = $partnerId; + } + + /** + * Get value of Address Verification Status / Card Verification Value option + * + * @return int Apply AVS/CV2 validation option + */ + public function getApplyAvsCv2() + { + return $this->_applyAvsCv2; + } + + /** + * Set value of Address Verification Status / Card Verification Value option + * + * @param int $applyAvsCv2 Apply AVS/CV2 validation option + */ + public function setApplyAvsCv2($applyAvsCv2) + { + if (in_array($applyAvsCv2, range(0, 3))) + { + $this->_applyAvsCv2 = $applyAvsCv2; + } + else + { + trigger_error("Invalid Apply AVS/CV2 value, [0, 1, 2, 3] expected, " . $applyAvsCv2 . " given", E_USER_WARNING); + } + } + + /** + * Get value of 3D Secure Verification option + * + * @return int 3D Secure Verification option + */ + public function getApply3dSecure() + { + return $this->_apply3dSecure; + } + + /** + * Set value of 3D Secure Verification option + * + * @param int $apply3dSecure 3D Secure Verification option + */ + public function setApply3dSecure($apply3dSecure) + { + if (in_array($apply3dSecure, range(0, 3))) + { + $this->_apply3dSecure = $apply3dSecure; + } + else + { + trigger_error("Invalid Apply 3D Secure value, [0, 1, 2, 3] expected, " . $apply3dSecure . " given", E_USER_WARNING); + } + } + + /** + * Get value of Allow gift aid option + * + * @return int Allow gift aid option + */ + public function getAllowGiftAid() + { + return $this->_allowGiftAid; + } + + /** + * Set value of Allow gift aid option + * + * @param int $allowGiftAid Allow gift aid option + */ + public function setAllowGiftAid($allowGiftAid) + { + if (in_array($allowGiftAid, range(0, 1))) + { + $this->_allowGiftAid = $allowGiftAid; + } + else + { + trigger_error("Invalid Allow Gift Aid value, [0, 1] expected, " . $allowGiftAid . " given", E_USER_WARNING); + } + } + + /** + * Get List of Surcharges + * + * @return array list of Surcharges + */ + public function getSurcharges() + { + return $this->_surcharges; + } + + /** + * Set list of Surcharges + * + * @param array $surcharges list of Surcharges + */ + public function setSurcharges($surcharges) + { + $this->_surcharges = $surcharges; + } + + /** + * Get value of Collect recipient details option + * + * @return boolean Collect recipient details option + */ + public function getCollectRecipientDetails() + { + return $this->_collectRecipientDetails; + } + + /** + * Set value of Collect recipient details option + * + * @param boolean $collect Collect recipient details option + */ + public function setCollectRecipientDetails($collect) + { + if (is_bool($collect)) + { + $this->_collectRecipientDetails = $collect; + } + else + { + trigger_error("Invalid Collect Recipient Details value, boolean expected, " . gettype($collect) . " given", E_USER_WARNING); + } + } + + /** + * Get list of FORM Protocol encryption password setting + * AES encryption password assigned to you by Sage Pay + * + * @return array list of FORM Protocol encryption password + */ + public function getFormPassword() + { + return $this->_formPassword; + } + + /** + * Set list of FORM Protocol encryption password setting + * AES encryption password assigned to you by Sage Pay + * + * @param array $formPassword list of FORM Protocol encryption password + */ + public function setFormPassword($formPassword) + { + $this->_formPassword = $formPassword; + } + + /** + * Get success page redirect for FORM Protocol + * + * @return string FORM Protocol success URL + */ + public function getFormSuccessUrl() + { + return $this->_formSuccessUrl; + } + + + /** + * Set success page redirect for FORM Protocol + * + * @param string $formSuccessUrl FORM Protocol success URL + */ + public function setFormSuccessUrl($formSuccessUrl) + { + $this->_formSuccessUrl = $formSuccessUrl; + } + + /** + * Get failure page redirect for FORM Protocol + * + * @return string FORM Protocol failure URL + */ + public function getFormFailureUrl() + { + return $this->_formFailureUrl; + } + + /** + * Set failure page redirect for FORM Protocol + * + * @param string $formFailureUrl FORM Protocol failure URL + */ + public function setFormFailureUrl($formFailureUrl) + { + $this->_formFailureUrl = $formFailureUrl; + } + + /** + * Get merchant account type + * + * @return type + */ + public function getAccountType() + { + return $this->_accountType; + } + + /** + * Set merchant account type + * + * @param string $accountType + */ + public function setAccountType($accountType) + { + if (in_array($accountType, array(SAGEPAY_ACCOUNT_ECOMMERCE, SAGEPAY_ACCOUNT_CONTINUOUS, SAGEPAY_ACCOUNT_MAIL))) + { + $this->_accountType = $accountType; + } + else + { + trigger_error("Invalid Account Type value, [E, C, M] expected, '" . $accountType . "' given", E_USER_WARNING); + } + } + + /** + * Get server profile used by default + * + * @return type SERVER Protocol profile + */ + public function getServerProfile() + { + return $this->_serverProfile; + } + + /** + * Set server profile used by default + * + * @param string $serverProfile SERVER Protocol profile + */ + public function setServerProfile($serverProfile) + { + if (in_array($serverProfile, array(SAGEPAY_SERVER_PROFILE_LOW, SAGEPAY_SERVER_PROFILE_NORMAL))) + { + $this->_serverProfile = $serverProfile; + } + else + { + trigger_error("Invalid Server Profile value, [NORMAL, LOW] expected, '" . $serverProfile . "' given", E_USER_WARNING); + } + } + + /** + * Get value for notification url called by Sagepay System for SERVER Protocol + * + * @return string SERVER Protocol Notification URL + */ + public function getServerNotificationUrl() + { + return $this->_serverNotificationUrl; + } + + /** + * Set value for notification url called by Sagepay System for SERVER Protocol + * + * @param string $serverNotificationUrl SERVER Protocol Notification URL + */ + public function setserverNotificationUrl($serverNotificationUrl) + { + $this->_serverNotificationUrl = $serverNotificationUrl; + } + + /** + * Get password salt for the local customer password database used by the kit + * + * @return string Password salt + */ + public function getCustomerPasswordSalt() + { + return $this->_customerPasswordSalt; + } + + /** + * Set password salt for the local customer password database used by the kit + * 7 chars length + * + * @param string $customerPasswordSalt Password salt + */ + public function setCustomerPasswordSalt($customerPasswordSalt) + { + $this->_customerPasswordSalt = substr($customerPasswordSalt, 0, 7); + } + + /** + * Get value of Billing Agreement option + * + * @return int Billing Agreement option + */ + public function getBillingAgreement() + { + return $this->_billingAgreement; + } + + /** + * Set value of Billing Agreement option + * + * @param int $billingAgreement Billing Agreement option + */ + public function setBillingAgreement($billingAgreement) + { + if (in_array($billingAgreement, array(0, 1), true)) + { + $this->_billingAgreement = $billingAgreement; + } + else + { + trigger_error("Invalid Billing Agreement value, [0, 1] expected, " . $billingAgreement . " given", E_USER_WARNING); + } + } + + /** + * Get value of Send e-mail option + * + * @return int Send e-mail option + */ + public function getSendEmail() + { + return $this->_sendEmail; + } + + /** + * Set value of Send e-mail option + * + * @param int $sendEmail Send e-mail option + */ + public function setSendEmail($sendEmail) + { + $this->_sendEmail = $sendEmail; + } + + /** + * Get e-mail message + * + * @return string E-mail message + */ + public function getEmailMessage() + { + return $this->_emailMessage; + } + + /** + * Set e-mail message + * + * @param string $emailMessage E-mail message + */ + public function setEmailMessage($emailMessage) + { + $this->_emailMessage = strip_tags($emailMessage); + } + + /** + * Get value of vendor email + * + * @return string Vendor email + */ + public function getVendorEmail() + { + return $this->_vendorEmail; + } + + /** + * Set value of vendor email + * + * @param string $vendorEmail Vendor email + */ + public function setVendorEmail($vendorEmail) + { + if (SagepayValid::email($vendorEmail)) + { + $this->_vendorEmail = $vendorEmail; + } + else + { + trigger_error("Invalid Vendor Email value, email format expected, '" . $vendorEmail . "' given", E_USER_WARNING); + } + } + + /** + * Get value of Basket as XML seeting + * + * @return boolean Basket as XML + */ + public function basketAsXmlDisabled() + { + return $this->_basketAsXmlDisable; + } + + /** + * Set value of Basket as XML seeting + * + * @param boolean $basketAsXmlDisable Basket as XML + */ + public function setBasketAsXmlDisable($basketAsXmlDisable) + { + if (is_bool($basketAsXmlDisable)) + { + $this->_basketAsXmlDisable = $basketAsXmlDisable; + } + else + { + trigger_error("Invalid Basket as XML value, boolean expected, " . gettype($basketAsXmlDisable) . " given", E_USER_WARNING); + } + } + + /** + * Get value of PayPal Callback URL + * + * @return string PayPal Callback URL + */ + public function getPaypalCallbackUrl() + { + return $this->_paypalCallbackUrl; + } + + /** + * Set value of PayPal Callback URL + * + * @param string $paypalCallbackUrl PayPal Callback URL + */ + public function setPaypalCallbackUrl($paypalCallbackUrl) + { + $this->_paypalCallbackUrl = $paypalCallbackUrl; + } + + /** + * Get list of Registration Service + * + * @return array List of Registration Service + */ + public function getPurchaseUrls() + { + return $this->_purchaseUrls; + } + + /** + * Set list of Registration Services + * + * @param array $purchaseUrls List of Registration Service + */ + public function setPurchaseUrls($purchaseUrls) + { + $this->_purchaseUrls = $this->_mergeEnvironmentUrls($this->_purchaseUrls, $purchaseUrls); + } + + /** + * Get list of Shared Services + * + * @return array List of Shared Services + */ + public function getSharedUrls() + { + return $this->_sharedUrls; + } + + /** + * Set list of Shared Services + * + * @param array $sharedUrls List of Shared Services + */ + public function setSharedUrls($sharedUrls) + { + $this->_sharedUrls = $this->_mergeEnvironmentUrls($this->_sharedUrls, $sharedUrls); + } + + /** + * Get list of Token Services + * + * @return array List of Token Services + */ + public function getTokenUrls() + { + return $this->_tokenUrls; + } + + /** + * Set list of Token Services + * + * @param array $tokenUrls List of Token Services + */ + public function setTokenUrls($tokenUrls) + { + $this->_tokenUrls = $this->_mergeEnvironmentUrls($this->_tokenUrls, $tokenUrls); + } + + /** + * Get Log Error option + * + * @return boolean + */ + public function getLogError() + { + return $this->_logError; + } + + /** + * Set Log Error option + * + * @param boolean $logError + */ + public function setLogError($logError) + { + if (is_bool($logError)) + { + $this->_logError = $logError; + } + else + { + trigger_error("Invalid Log Error, boolean expected, " . gettype($logError) . " given", E_USER_WARNING); + } + } + + /** + * Get language value ISO 639-1 valid + * + * @return type + */ + public function getLanguage() + { + return $this->_language; + } + + /** + * Get language value ISO 639-1 valid + * @link http://en.wikipedia.org/wiki/ISO_639 + * + * @param type $language + */ + public function setLanguage($language) + { + $this->_language = substr($language, 0, 2); + } + + /** + * Get reference to the website this transaction came from. + * + * @return type + */ + public function getWebsite() + { + return $this->_website; + } + + /** + * Set reference to the website this transaction came from. + * + * @param type $website + */ + public function setWebsite($website) + { + if (!empty($website) && SagepayValid::url($website)) + { + $this->_website = $website; + } + else + { + trigger_error("Invalid Website URL value, email format expected, '" . $website . "' given", E_USER_WARNING); + } + } + + /** + * Get timeout for POST cURL requests + * + * @return int + */ + public function getRequestTimeout() + { + return $this->_requestTimeout; + } + + /** + * Set timeout for POST cURL requests + * + * @param int $ttl + */ + public function setRequestTimeout($ttl) + { + if (is_int($ttl)) + { + $this->_requestTimeout = $ttl; + } + else + { + trigger_error("Invalid request timeout value, integer expected, '" . $ttl . "' given", E_USER_WARNING); + } + } + + /** + * Get CACert file path + * + * @return string + */ + public function getCaCertPath() + { + return $this->_caCertPath; + } + + /** + * Set CACert file path + * + * @param string $caCertPath + */ + public function setCaCertPath($caCertPath) + { + $this->_caCertPath = $caCertPath; + } + + /** + * Get value of siteFqdn for specific environment + * + * @param string $env Specific environment + * + * @return string SiteFqdn URL + */ + public function getSiteFqdn($env = '') + { + $env = $this->_validEnvironment($env); + return $this->_siteFqdn[$env]; + } + + /** + * Set value of siteFqdn for specific environment + * + * @param string $siteFqdn SiteFqdn URL + * @param string $env Specific environment + */ + public function setSiteFqdn($siteFqdn, $env = '') + { + $env = $this->_validEnvironment($env); + $this->_siteFqdn[$env] = $siteFqdn; + } + + /** + * Set Encryption password for specific environment + * + * @param string $password Encryption password + * @param string $env Environment name, by default is using current environment value + */ + public function setFormEncryptionPassword($password, $env = '') + { + $env = $this->_validEnvironment($env); + $this->_formPassword[$env] = $password; + } + + + /** + * Get full URL for Form Successes + * + * @param string $env Specific environment + * @return string + */ + public function getFullFormSuccessUrl($env = '') + { + $base = $this->getSiteFqdn($env); + return $base . $this->_formSuccessUrl; + } + + /** + * Get full URL for Form Failures + * + * @param string $env Specific environment + * @return string + */ + public function getFullFormFailureUrl($env = '') + { + $base = $this->getSiteFqdn($env); + return $base . $this->_formFailureUrl; + } + + /** + * Get full URL for Server Notifications + * + * @param string $env Specific environment + * @return string + */ + public function getFullServerNotificationUrl($env = '') + { + $base = $this->getSiteFqdn($env); + return $base . $this->_serverNotificationUrl; + } + + /** + * Get Encryption password for specific environment + * + * @param string $env Environment name, by default is using current environment value + * + * @return string Encryption password + */ + public function getFormEncryptionPassword($env = '') + { + $env = $this->_validEnvironment($env); + return $this->_formPassword[$env]; + } + + /** + * Get value of specific Registration Service + * + * @param string $method Method alias + * @param string $env Environment name, by default is using current environment value + * + * @return string Registration Service URL + */ + public function getPurchaseUrl($method, $env = '') + { + $env = $this->_validEnvironment($env); + if (isset($this->_purchaseUrls[$env][$method])) + { + return $this->_purchaseUrls[$env][$method]; + } + return ''; + } + + /** + * Set value of specific method of Registration Services + * + * @param string $purchaseUrl Registration Service URL + * @param string $method Method alias + * @param string $env Environment name, by default is using current environment value + */ + public function setPurchaseUrl($purchaseUrl, $method, $env = '') + { + $env = $this->_validEnvironment($env); + if (!empty($method) && !empty($purchaseUrl)) + { + $this->_purchaseUrls[$env][$method] = $purchaseUrl; + } + } + + /** + * Get value of specific method of Shared Services + * + * @param string $method Method alias + * @param string $env Environment name, by default is using current environment value + * + * @return string Shared Service URL + */ + public function getSharedUrl($method, $env = '') + { + $env = $this->_validEnvironment($env); + if (isset($this->_sharedUrls[$env][$method])) + { + return $this->_sharedUrls[$env][$method]; + } + return ''; + } + + /** + * Set value of specific method of Shared Services + * + * @param string $sharedUrl Shared Service URL + * @param string $method Method alias + * @param string $env Environment name, by default is using current environment value + */ + public function setSharedUrl($sharedUrl, $method, $env = '') + { + $env = $this->_validEnvironment($env); + if (!empty($method) && !empty($sharedUrl)) + { + $this->_sharedUrls[$env][$method] = $sharedUrl; + } + } + + /** + * Get url for specific token service and environment + * + * @param string $method Method name + * @param string $env Environment name, by default is using current environment value + * + * @return string Token Service URL + */ + public function getTokenUrl($method, $env = '') + { + + $env = $this->_validEnvironment($env); + if (isset($this->_tokenUrls[$env][$method])) + { + return $this->_tokenUrls[$env][$method]; + } + return ''; + } + + /** + * Set url for specific token service and environment + * + * @param string $tokenUrl Token Service URL + * @param string $method Method name + * @param string $env Environment name, by default is using current environment value + */ + public function setTokenUrl($tokenUrl, $method, $env = '') + { + $env = $this->_validEnvironment($env); + if (!empty($method) && !empty($tokenUrl)) + { + $this->_tokenUrls[$env][$method] = $tokenUrl; + } + } + + /** + * Load file configuration and return the $config array + * + * @return array Configuration + */ + private function _loadFileConfig() + { + return include SAGEPAY_SDK_PATH . '/config.php'; + } + + /** + * Insert values of array config into current instance SagepayConfig + * + * @param array $config + */ + private function _applyConfig(array $config) + { + foreach ($config as $key => $val) + { + $prop = 'set' . ucfirst($key); + if (method_exists($this, $prop)) + { + $this->$prop($val); + } + } + } + + /** + * Validate value for environment + * Set up current env if it is missing or is not valid environment + * + * @param string $env Environment + * + * @return string Environment + */ + private function _validEnvironment($env) + { + if (!in_array($env, array(SAGEPAY_ENV_TEST, SAGEPAY_ENV_LIVE))) + { + return $this->_env; + } + return $env; + } + + /** + * Recursive merge of URLs + * + * @param array $oldUrls Old URLs values + * @param array $newUrls New URLs values + * + * @return array + */ + private function _mergeEnvironmentUrls(array $oldUrls, array $newUrls) + { + foreach ($oldUrls as $env => $methods) + { + foreach (array_keys($methods) as $method) + { + if (isset($newUrls[$env][$method]) && !empty($newUrls[$env][$method])) + { + $oldUrls[$env][$method] = $newUrls[$env][$method]; + } + } + } + return $oldUrls; + } + +} diff --git a/src/Sagepay/classes/surcharge.php b/src/Sagepay/classes/surcharge.php index 38f75a5..829a017 100755 --- a/src/Sagepay/classes/surcharge.php +++ b/src/Sagepay/classes/surcharge.php @@ -1,127 +1,127 @@ -_surcharges; - } - - /** - * Set surcharges - * - * @param array $surcharges - */ - public function setSurcharges($surcharges) - { - $this->_surcharges = $surcharges; - } - - /** - * Add a surcharge to list - * - * @param array $surcharge - */ - private function _addSurcharge($surcharge) - { - $this->_surcharges[] = $surcharge; - } - - /** - * List of fields that should be exported to surcharges XML - * - * @var array - */ - private $_exportFields = array( - 'paymentType', - 'percentage', - 'fixed', - ); - - /** - * Add surcharge by details - * @uses SagepayUtil::cardTypes List of cards - * - * @param string $paymentType - * @param float $percentage - * @param float $fixed - * - * @return boolean - */ - public function addSurchargeDetails($paymentType, $percentage = null, $fixed = null) - { - if (!in_array(strtolower($paymentType), SagepayUtil::cardTypes())) - { - return false; - } - - $surcharge = array('paymentType' => $paymentType); - if (!empty($percentage)) - { - $surcharge['percentage'] = $percentage; - $this->_addSurcharge($surcharge); - return true; - } - - if (!empty($fixed)) - { - $surcharge['fixed'] = $fixed; - $this->_addSurcharge($surcharge); - return true; - } - - return false; - } - - /** - * Export surcharges details as XML string - * - * @return string XML with surcharges details - */ - public function export() - { - $dom = new DOMDocument(); - $dom->loadXML(""); - - foreach ($this->_surcharges as $surcharge) - { - $surchargeEl = $dom->createElement('surcharge'); - $exportFieldsCount = 0; - foreach ($this->_exportFields as $field) - { - if (isset($surcharge[$field]) && $exportFieldsCount < 2) - { - $exportFieldsCount++; - $node = $dom->createElement($field, $surcharge[$field]); - $surchargeEl->appendChild($node); - } - } - $dom->documentElement->appendChild($surchargeEl); - } - - return $dom->saveXML($dom->documentElement); - } - -} +_surcharges; + } + + /** + * Set surcharges + * + * @param array $surcharges + */ + public function setSurcharges($surcharges) + { + $this->_surcharges = $surcharges; + } + + /** + * Add a surcharge to list + * + * @param array $surcharge + */ + private function _addSurcharge($surcharge) + { + $this->_surcharges[] = $surcharge; + } + + /** + * List of fields that should be exported to surcharges XML + * + * @var array + */ + private $_exportFields = array( + 'paymentType', + 'percentage', + 'fixed', + ); + + /** + * Add surcharge by details + * @uses SagepayUtil::cardTypes List of cards + * + * @param string $paymentType + * @param float $percentage + * @param float $fixed + * + * @return boolean + */ + public function addSurchargeDetails($paymentType, $percentage = null, $fixed = null) + { + if (!in_array(strtolower($paymentType), SagepayUtil::cardTypes())) + { + return false; + } + + $surcharge = array('paymentType' => $paymentType); + if (!empty($percentage)) + { + $surcharge['percentage'] = $percentage; + $this->_addSurcharge($surcharge); + return true; + } + + if (!empty($fixed)) + { + $surcharge['fixed'] = $fixed; + $this->_addSurcharge($surcharge); + return true; + } + + return false; + } + + /** + * Export surcharges details as XML string + * + * @return string XML with surcharges details + */ + public function export() + { + $dom = new DOMDocument(); + $dom->loadXML(""); + + foreach ($this->_surcharges as $surcharge) + { + $surchargeEl = $dom->createElement('surcharge'); + $exportFieldsCount = 0; + foreach ($this->_exportFields as $field) + { + if (isset($surcharge[$field]) && $exportFieldsCount < 2) + { + $exportFieldsCount++; + $node = $dom->createElement($field, $surcharge[$field]); + $surchargeEl->appendChild($node); + } + } + $dom->documentElement->appendChild($surchargeEl); + } + + return $dom->saveXML($dom->documentElement); + } + +} diff --git a/src/Sagepay/classes/token.php b/src/Sagepay/classes/token.php index 9ded9e1..b54afdf 100755 --- a/src/Sagepay/classes/token.php +++ b/src/Sagepay/classes/token.php @@ -1,176 +1,176 @@ -_config = $config; - $this->_registerUrl = $config->getTokenUrl('register-direct'); - $this->_removeUrl = $config->getTokenUrl('remove'); - } - - /** - * Get URL for card registration [RFC1738 valid] - * - * @return string - */ - public function getRegisterUrl() - { - return $this->_registerUrl; - } - - /** - * Set URL for card registration [RFC1738 valid] - * - * @uses SagepayValid::url Validate URL field - * @param string $registerUrl - */ - public function setRegisterUrl($registerUrl) - { - if (SagepayValid::url($registerUrl)) - { - $this->_registerUrl = $registerUrl; - } - } - - /** - * Get URL for card remove [RFC1738 valid] - * - * @return string - */ - public function getRemoveUrl() - { - return $this->_removeUrl; - } - - /** - * Set URL for card remove [RFC1738 valid] - * - * @uses SagepayValid::url Validate URL field - * @param string $removeUrl - */ - public function setRemoveUrl($removeUrl) - { - if (SagepayValid::url($removeUrl)) - { - $this->_removeUrl = $removeUrl; - } - } - - /** - * Prepare data for register request - * - * @param array $cardDetails - * @return array - */ - private function _prepareRegisterData(array $cardDetails) - { - return array( - 'VPSProtocol' => $this->_config->getProtocolVersion(), - 'TxType' => self::TOKEN, - 'Vendor' => $this->_config->getVendorName(), - 'Currency' => $this->_config->getCurrency(), - 'CardHolder' => isset($cardDetails['cardHolder']) ? $cardDetails['cardHolder'] : NULL, - 'CardNumber' => isset($cardDetails['cardNumber']) ? $cardDetails['cardNumber'] : NULL, - 'ExpiryDate' => isset($cardDetails['expiryDate']) ? $cardDetails['expiryDate'] : NULL, - 'CV2' => isset($cardDetails['cv2']) ? $cardDetails['cv2'] : NULL, - 'CardType' => isset($cardDetails['cardType']) ? $cardDetails['cardType'] : NULL, - ); - } - - /** - * Prepare data for remove request - * - * @param string $token - * @return array - */ - private function _prepareRemoveData($token) - { - return array( - 'VPSProtocol' => $this->_config->getProtocolVersion(), - 'TxType' => self::REMOVETOKEN, - 'Vendor' => $this->_config->getVendorName(), - 'Token' => $token, - ); - } - - /** - * Register card to Sagepay Service - * - * @param string[] $cardDetails Associative array with card details - * - * @return string|null - */ - public function register(array $cardDetails) - { - $data = $this->_prepareRegisterData($cardDetails); - $ttl = $this->_config->getRequestTimeout(); - $caCert = $this->_config->getCaCertPath(); - $response = SagepayCommon::requestPost($this->_registerUrl, $data, $ttl, $caCert); - return isset($response['Token']) ? $response['Token'] : NULL; - } - - /** - * Remove token from Sagepay Service - * - * @param string $token Token GUID provided by Sagepay service on card registration - * - * @return boolean - */ - public function remove($token) - { - $data = $this->_prepareRemoveData($token); - $ttl = $this->_config->getRequestTimeout(); - $caCert = $this->_config->getCaCertPath(); - $response = SagepayCommon::requestPost($this->_removeUrl, $data, $ttl, $caCert); - return ($response['Status'] == SAGEPAY_REMOTE_STATUS_OK); - } - -} +_config = $config; + $this->_registerUrl = $config->getTokenUrl('register-direct'); + $this->_removeUrl = $config->getTokenUrl('remove'); + } + + /** + * Get URL for card registration [RFC1738 valid] + * + * @return string + */ + public function getRegisterUrl() + { + return $this->_registerUrl; + } + + /** + * Set URL for card registration [RFC1738 valid] + * + * @uses SagepayValid::url Validate URL field + * @param string $registerUrl + */ + public function setRegisterUrl($registerUrl) + { + if (SagepayValid::url($registerUrl)) + { + $this->_registerUrl = $registerUrl; + } + } + + /** + * Get URL for card remove [RFC1738 valid] + * + * @return string + */ + public function getRemoveUrl() + { + return $this->_removeUrl; + } + + /** + * Set URL for card remove [RFC1738 valid] + * + * @uses SagepayValid::url Validate URL field + * @param string $removeUrl + */ + public function setRemoveUrl($removeUrl) + { + if (SagepayValid::url($removeUrl)) + { + $this->_removeUrl = $removeUrl; + } + } + + /** + * Prepare data for register request + * + * @param array $cardDetails + * @return array + */ + private function _prepareRegisterData(array $cardDetails) + { + return array( + 'VPSProtocol' => $this->_config->getProtocolVersion(), + 'TxType' => self::TOKEN, + 'Vendor' => $this->_config->getVendorName(), + 'Currency' => $this->_config->getCurrency(), + 'CardHolder' => isset($cardDetails['cardHolder']) ? $cardDetails['cardHolder'] : NULL, + 'CardNumber' => isset($cardDetails['cardNumber']) ? $cardDetails['cardNumber'] : NULL, + 'ExpiryDate' => isset($cardDetails['expiryDate']) ? $cardDetails['expiryDate'] : NULL, + 'CV2' => isset($cardDetails['cv2']) ? $cardDetails['cv2'] : NULL, + 'CardType' => isset($cardDetails['cardType']) ? $cardDetails['cardType'] : NULL, + ); + } + + /** + * Prepare data for remove request + * + * @param string $token + * @return array + */ + private function _prepareRemoveData($token) + { + return array( + 'VPSProtocol' => $this->_config->getProtocolVersion(), + 'TxType' => self::REMOVETOKEN, + 'Vendor' => $this->_config->getVendorName(), + 'Token' => $token, + ); + } + + /** + * Register card to Sagepay Service + * + * @param string[] $cardDetails Associative array with card details + * + * @return string|null + */ + public function register(array $cardDetails) + { + $data = $this->_prepareRegisterData($cardDetails); + $ttl = $this->_config->getRequestTimeout(); + $caCert = $this->_config->getCaCertPath(); + $response = SagepayCommon::requestPost($this->_registerUrl, $data, $ttl, $caCert); + return isset($response['Token']) ? $response['Token'] : NULL; + } + + /** + * Remove token from Sagepay Service + * + * @param string $token Token GUID provided by Sagepay service on card registration + * + * @return boolean + */ + public function remove($token) + { + $data = $this->_prepareRemoveData($token); + $ttl = $this->_config->getRequestTimeout(); + $caCert = $this->_config->getCaCertPath(); + $response = SagepayCommon::requestPost($this->_removeUrl, $data, $ttl, $caCert); + return ($response['Status'] == SAGEPAY_REMOTE_STATUS_OK); + } + +} diff --git a/src/Sagepay/classes/valid.php b/src/Sagepay/classes/valid.php index 7c75666..ae97d28 100755 --- a/src/Sagepay/classes/valid.php +++ b/src/Sagepay/classes/valid.php @@ -1,222 +1,222 @@ - 0; - } - - /** - * Checks a field against a regular expression. - * - * @param string $input value - * @param string $regexp regular expression to match (including delimiters) - * - * @return boolean - */ - public static function regex($input, $regexp) - { - return (bool) preg_match($regexp, (string) $input); - } - - /** - * Checks that a field is greater or equal with minimum required. - * - * @param string $input value - * @param integer $length minimum length required - * - * @return boolean - */ - public static function minLength($input, $length) - { - return strlen($input) >= $length; - } - - /** - * Checks that a field is less or equal with maximum required - * - * @param string $input value - * @param integer $length maximum length required - * - * @return boolean - */ - public static function maxLength($input, $length) - { - return strlen($input) <= $length; - } - - /** - * Checks that a number is within a range. - * - * @param string $input number to check - * @param integer $minValue minimum value - * @param integer $maxValue maximum value - * - * @return boolean - */ - public static function range($input, $minValue, $maxValue) - { - return ($input >= $minValue && $input <= $maxValue); - } - - /** - * Checks that a field have exact length. - * - * @param string $input value - * @param integer|array $length exact length required, or array of valid lengths - * - * @return boolean - */ - public static function exactLength($input, $length) - { - if (is_array($length)) - { - foreach ($length as $specificLength) - { - if (strlen($input) === $specificLength) - { - return TRUE; - } - } - return FALSE; - } - - return strlen($input) === $length; - } - - /** - * Checks that a field is same as required. - * - * @param string $input original value - * @param string $expected expected value - * - * @return boolean - */ - public static function equals($input, $expected) - { - return ($input === $expected); - } - - /** - * Check an email address for valid format. - * - * @param string $input email address - * - * @return boolean - */ - public static function email($input) - { - if ($input === '') - { - return true; - } - return (bool) filter_var($input, FILTER_VALIDATE_EMAIL); - } - - /** - * Check an URL for valid format. - * - * @param string $input URL - * - * @return boolean - */ - static public function url($input) - { - return (bool) filter_var($input, FILTER_VALIDATE_URL); - } - - /** - * Validates a credit card number with luhn checksum - * - * @uses SagepayValid::luhn - * @param integer $input credit card number - * - * @return boolean - */ - public static function creditCard($input) - { - $input = preg_replace('/\D+/', '', $input); - return self::luhn($input); - } - - /** - * Validate a number against the Luhn checksum - * - * @link http://en.wikipedia.org/wiki/Luhn_algorithm - * @param string $input number to check - * - * @return boolean - */ - public static function luhn($input) - { - if (!ctype_digit($input)) - { - return FALSE; - } - - $checksum = ''; - - foreach (str_split(strrev($input)) as $i => $d) - { - $checksum .= $i % 2 !== 0 ? $d * 2 : $d; - } - - return array_sum(str_split($checksum)) % 10 === 0; - } - - /** - * Checks whether a string consists of digits only. - * - * @param string $input input string - * - * @return boolean - */ - public static function digit($input) - { - return (is_int($input) && $input >= 0) || ctype_digit($input); - } - - /** - * Checks whether a string is a valid number. - * - * @param string $input input string - * - * @return boolean - */ - public static function numeric($input) - { - return (bool) preg_match('/^-?+(?=.*[0-9])[0-9]*+[,\.]?+[0-9]*+$/D', $input); - } - - /** - * Checks if a string is a proper decimal format. - * - * @param string $input number to check - * @param integer $places number of decimal places - * - * @return boolean - */ - public static function decimal($input, $places = 2) - { - return (bool) preg_match('/^[+-]?[0-9]+[,\.][0-9]{' . ((int) $places) . '}$/D', $input); - } - -} + 0; + } + + /** + * Checks a field against a regular expression. + * + * @param string $input value + * @param string $regexp regular expression to match (including delimiters) + * + * @return boolean + */ + public static function regex($input, $regexp) + { + return (bool) preg_match($regexp, (string) $input); + } + + /** + * Checks that a field is greater or equal with minimum required. + * + * @param string $input value + * @param integer $length minimum length required + * + * @return boolean + */ + public static function minLength($input, $length) + { + return strlen($input) >= $length; + } + + /** + * Checks that a field is less or equal with maximum required + * + * @param string $input value + * @param integer $length maximum length required + * + * @return boolean + */ + public static function maxLength($input, $length) + { + return strlen($input) <= $length; + } + + /** + * Checks that a number is within a range. + * + * @param string $input number to check + * @param integer $minValue minimum value + * @param integer $maxValue maximum value + * + * @return boolean + */ + public static function range($input, $minValue, $maxValue) + { + return ($input >= $minValue && $input <= $maxValue); + } + + /** + * Checks that a field have exact length. + * + * @param string $input value + * @param integer|array $length exact length required, or array of valid lengths + * + * @return boolean + */ + public static function exactLength($input, $length) + { + if (is_array($length)) + { + foreach ($length as $specificLength) + { + if (strlen($input) === $specificLength) + { + return TRUE; + } + } + return FALSE; + } + + return strlen($input) === $length; + } + + /** + * Checks that a field is same as required. + * + * @param string $input original value + * @param string $expected expected value + * + * @return boolean + */ + public static function equals($input, $expected) + { + return ($input === $expected); + } + + /** + * Check an email address for valid format. + * + * @param string $input email address + * + * @return boolean + */ + public static function email($input) + { + if ($input === '') + { + return true; + } + return (bool) filter_var($input, FILTER_VALIDATE_EMAIL); + } + + /** + * Check an URL for valid format. + * + * @param string $input URL + * + * @return boolean + */ + static public function url($input) + { + return (bool) filter_var($input, FILTER_VALIDATE_URL); + } + + /** + * Validates a credit card number with luhn checksum + * + * @uses SagepayValid::luhn + * @param integer $input credit card number + * + * @return boolean + */ + public static function creditCard($input) + { + $input = preg_replace('/\D+/', '', $input); + return self::luhn($input); + } + + /** + * Validate a number against the Luhn checksum + * + * @link http://en.wikipedia.org/wiki/Luhn_algorithm + * @param string $input number to check + * + * @return boolean + */ + public static function luhn($input) + { + if (!ctype_digit($input)) + { + return FALSE; + } + + $checksum = ''; + + foreach (str_split(strrev($input)) as $i => $d) + { + $checksum .= $i % 2 !== 0 ? $d * 2 : $d; + } + + return array_sum(str_split($checksum)) % 10 === 0; + } + + /** + * Checks whether a string consists of digits only. + * + * @param string $input input string + * + * @return boolean + */ + public static function digit($input) + { + return (is_int($input) && $input >= 0) || ctype_digit($input); + } + + /** + * Checks whether a string is a valid number. + * + * @param string $input input string + * + * @return boolean + */ + public static function numeric($input) + { + return (bool) preg_match('/^-?+(?=.*[0-9])[0-9]*+[,\.]?+[0-9]*+$/D', $input); + } + + /** + * Checks if a string is a proper decimal format. + * + * @param string $input number to check + * @param integer $places number of decimal places + * + * @return boolean + */ + public static function decimal($input, $places = 2) + { + return (bool) preg_match('/^[+-]?[0-9]+[,\.][0-9]{' . ((int) $places) . '}$/D', $input); + } + +} diff --git a/src/Sagepay/classes/validator.php b/src/Sagepay/classes/validator.php index bd4fc07..2e39c27 100755 --- a/src/Sagepay/classes/validator.php +++ b/src/Sagepay/classes/validator.php @@ -1,91 +1,91 @@ -_errors[] = $validMethod[1]; - $this->_isValid = false; - break; - } - } - } - - /** - * Get validation result - * - * @return boolean - */ - public function isValid() - { - return $this->_isValid; - } - - /** - * Get validation errors as array - * - * @return string[] - */ - public function getErrors() - { - return $this->_errors; - } - -} - +_errors[] = $validMethod[1]; + $this->_isValid = false; + break; + } + } + } + + /** + * Get validation result + * + * @return boolean + */ + public function isValid() + { + return $this->_isValid; + } + + /** + * Get validation errors as array + * + * @return string[] + */ + public function getErrors() + { + return $this->_errors; + } + +} + diff --git a/src/Sagepay/config.php b/src/Sagepay/config.php index 3e02c0a..e23fa0a 100755 --- a/src/Sagepay/config.php +++ b/src/Sagepay/config.php @@ -1,148 +1,148 @@ - value or 'value' -// -// All keys must be present or an exception will be thrown. -// -// Mandatory Properties: -// Must have a value provided (or an exception will be thrown) -// -// Optional Properties: -// May or may not have a value -// - -defined('SAGEPAY_SDK_PATH') || exit('No direct script access.'); - -/** - * Setting the PHP error reporting level to -1 essentially forces PHP to - * report every error, and is guranteed to show every error on future - * versions of PHP. This will insure that our handlers above are - * notified about everything. - */ -error_reporting(-1); - -/** - * At the same time we want to disable PHP's default error display since - * we are now using our own. - */ -ini_set('display_errors', 'Off'); - -// Configuration file -return array( -// Mandatory parameter -// Set to any of: TEST for the Test Server and LIVE for the live environment - 'env' => 'test', -// Optional parameter supported protocol version (3.00 is the newest and the only available) - 'protocolVersion' => 3.00, -// Mandatory. Set this value to the Vendor Name assigned to you by Sage Pay or chosen when you applied - 'vendorName' => 'protxross', -// Mandatory. Set this to indicate the currency in which you wish to trade. -// You will need a merchant number in this currency - 'currency' => 'GBP', -// Mandatory. Usually PAYMENT. This can be DEFERRED or AUTHENTICATE if your Sage Pay -// account supports those payment types -// NB Ideally all DEFERRED transaction should be released within 6 days (according to card scheme rules). -// DEFERRED transactions can be ABORTed before a RELEASE if necessary - 'txType' => 'PAYMENT', -// Mandatory -// Qualified Domain Name of your server. -// This should start http:// or https:// and should be the name by which our servers can call back to yours -// i.e. it MUST be resolvable externally, and have access granted to the Sage Pay servers -// examples would be https://www.mysite.com or http://212.111.32.22/ - 'siteFqdns' => - array( - 'live' => '', - 'test' => 'http://192.168.13.11/VspPHPKit/', - ), -// Optional setting. If you are a Sage Pay Partner and wish to flag the transactions -// with your unique partner id, it should be set here - 'partnerId' => '', -// Optional setting to set vendor data - 'vendorData' => '', -// Optional -// 0 = If AVS/CV2 enabled then check them. If rules apply, use rules (default). -// 1 = Force AVS/CV2 checks even if not enabled for the account. If rules apply, use rules. -// 2 = Force NO AVS/CV2 checks even if enabled on account. -// 3 = Force AVS/CV2 checks even if not enabled for the account but DON'T apply any rules. - 'applyAvsCv2' => 0, -// Optional -// 0 = If 3D-Secure checks are possible and rules allow, perform the checks and apply the authorisation rules. (default) -// 1 = Force 3D-Secure checks for this transaction if possible and apply rules for authorisation. -// 2 = Do not perform 3D-Secure checks for this transaction and always authorise. -// 3 = Force 3D-Secure checks for this transaction if possible but ALWAYS obtain an auth code, irrespective of rule base. - 'apply3dSecure' => 0, -// Optional property. (Server & Form protocols only) -// For charities registered for Gift Aid, set to 1 to display the Gift Aid check -// box on the payment pages, or else 0 - 'allowGiftAid' => 1, -// Optional -// Use this to send surcharge xml and override the default values set for your account. -// See the protocol docs for further explanation on using the surcharge xml. - 'surcharges' => - array( - array( - 'paymentType' => 'MC', - 'percentage' => 5, - ), - array( - 'paymentType' => 'VISA', - 'fixed' => 3.5, - ), - ), -// Optional setting. if you are a vendor that has a merchant category code of 6012, then you can fill in extra details required for authorisation for Visa transactions - 'collectRecipientDetails' => false, -// Mandatory property, set this value to the Encryption password assigned to you by Sage Pay - 'formPassword' => - array( - 'test' => 'TPjs72eMz5qBnaTa', - 'live' => '', - ), -// Mandatory parameters form notifications URLs appended to siteFQDN value - 'formSuccessUrl' => 'form/success', - 'formFailureUrl' => 'form/failure', -//Optional setting. Set to tell the Sage Pay System which merchant account to use. If omitted, -// the system will use E, then M, then C by default -// E = Use the e-commerce merchant account (default) -// M = Use the mail order/telephone order account (if present) -// C = Use the continuous authority merchant account (if present) - 'accountType' => 'E', -// Mandatory Server notification URLs - 'serverNotificationUrl' => '', -// Optional -// 0 = Do not send either customer or vendor e-mails, -// 1 = Send customer and vendor e-mails if address(es) are provided(DEFAULT). -// 2 = Send Vendor Email but not Customer Email. If you do not supply this field, 1 is assumed and e-mails are sent if addresses are provided. - 'sendEmail' => 0, -// Optional -// You can specify any custom message to send to your customers in their confirmation e-mail here -// The field can contain HTML if you wish, and be different for each order. This field is optional - 'emailMessage' => '', -// Optional setting. Set this to the mail address which will receive order confirmations and failures - 'vendorEmail' => '', -// Optional parameter, this value will be used to set the BillingAgreement field in the registration POST -// A default is value of 0 is used if this parameter is not included in this properties file - 'billingAgreement' => 1, -// Mandatory parameter, salt used for hashing the password in the local database -// i.e. value: q8W#e1_ - 'customerPasswordSalt' => '', -// Optional parameter, set this to true to use colon delimited format for the basket instead of XML -// Note: The 'Trips' details on the 'Extra Information' page will not be displayed if this flag is set to true. - 'basketAsXmlDisable' => false, -// Set this to true if you want to store all logs in debug.log file - 'logError' => true, -// Optional -// The language the customer sees the payment pages in is determined by the code sent here. If this is NULL then the language default of the shoppers browser will be used. -// If the language is not supported then the language supported in the templates will be used -// Currently supported languages in the Default templates are : -// French, German, Spanish, Portuguese, Dutch and English - 'language' => null, -// Optional parameter reference to the website this transaction came from. This field is useful if transactions can originate from more than one website. Supplying this information will enable reporting to be performed by website. - 'website' => '', - 'requestTimeout' => 30, - 'caCertPath' => '', -); + value or 'value' +// +// All keys must be present or an exception will be thrown. +// +// Mandatory Properties: +// Must have a value provided (or an exception will be thrown) +// +// Optional Properties: +// May or may not have a value +// + +defined('SAGEPAY_SDK_PATH') || exit('No direct script access.'); + +/** + * Setting the PHP error reporting level to -1 essentially forces PHP to + * report every error, and is guranteed to show every error on future + * versions of PHP. This will insure that our handlers above are + * notified about everything. + */ +error_reporting(-1); + +/** + * At the same time we want to disable PHP's default error display since + * we are now using our own. + */ +ini_set('display_errors', 'Off'); + +// Configuration file +return array( +// Mandatory parameter +// Set to any of: TEST for the Test Server and LIVE for the live environment + 'env' => 'test', +// Optional parameter supported protocol version (3.00 is the newest and the only available) + 'protocolVersion' => 3.00, +// Mandatory. Set this value to the Vendor Name assigned to you by Sage Pay or chosen when you applied + 'vendorName' => 'protxross', +// Mandatory. Set this to indicate the currency in which you wish to trade. +// You will need a merchant number in this currency + 'currency' => 'GBP', +// Mandatory. Usually PAYMENT. This can be DEFERRED or AUTHENTICATE if your Sage Pay +// account supports those payment types +// NB Ideally all DEFERRED transaction should be released within 6 days (according to card scheme rules). +// DEFERRED transactions can be ABORTed before a RELEASE if necessary + 'txType' => 'PAYMENT', +// Mandatory +// Qualified Domain Name of your server. +// This should start http:// or https:// and should be the name by which our servers can call back to yours +// i.e. it MUST be resolvable externally, and have access granted to the Sage Pay servers +// examples would be https://www.mysite.com or http://212.111.32.22/ + 'siteFqdns' => + array( + 'live' => '', + 'test' => 'http://192.168.13.11/VspPHPKit/', + ), +// Optional setting. If you are a Sage Pay Partner and wish to flag the transactions +// with your unique partner id, it should be set here + 'partnerId' => '', +// Optional setting to set vendor data + 'vendorData' => '', +// Optional +// 0 = If AVS/CV2 enabled then check them. If rules apply, use rules (default). +// 1 = Force AVS/CV2 checks even if not enabled for the account. If rules apply, use rules. +// 2 = Force NO AVS/CV2 checks even if enabled on account. +// 3 = Force AVS/CV2 checks even if not enabled for the account but DON'T apply any rules. + 'applyAvsCv2' => 0, +// Optional +// 0 = If 3D-Secure checks are possible and rules allow, perform the checks and apply the authorisation rules. (default) +// 1 = Force 3D-Secure checks for this transaction if possible and apply rules for authorisation. +// 2 = Do not perform 3D-Secure checks for this transaction and always authorise. +// 3 = Force 3D-Secure checks for this transaction if possible but ALWAYS obtain an auth code, irrespective of rule base. + 'apply3dSecure' => 0, +// Optional property. (Server & Form protocols only) +// For charities registered for Gift Aid, set to 1 to display the Gift Aid check +// box on the payment pages, or else 0 + 'allowGiftAid' => 1, +// Optional +// Use this to send surcharge xml and override the default values set for your account. +// See the protocol docs for further explanation on using the surcharge xml. + 'surcharges' => + array( + array( + 'paymentType' => 'MC', + 'percentage' => 5, + ), + array( + 'paymentType' => 'VISA', + 'fixed' => 3.5, + ), + ), +// Optional setting. if you are a vendor that has a merchant category code of 6012, then you can fill in extra details required for authorisation for Visa transactions + 'collectRecipientDetails' => false, +// Mandatory property, set this value to the Encryption password assigned to you by Sage Pay + 'formPassword' => + array( + 'test' => 'TPjs72eMz5qBnaTa', + 'live' => '', + ), +// Mandatory parameters form notifications URLs appended to siteFQDN value + 'formSuccessUrl' => 'form/success', + 'formFailureUrl' => 'form/failure', +//Optional setting. Set to tell the Sage Pay System which merchant account to use. If omitted, +// the system will use E, then M, then C by default +// E = Use the e-commerce merchant account (default) +// M = Use the mail order/telephone order account (if present) +// C = Use the continuous authority merchant account (if present) + 'accountType' => 'E', +// Mandatory Server notification URLs + 'serverNotificationUrl' => '', +// Optional +// 0 = Do not send either customer or vendor e-mails, +// 1 = Send customer and vendor e-mails if address(es) are provided(DEFAULT). +// 2 = Send Vendor Email but not Customer Email. If you do not supply this field, 1 is assumed and e-mails are sent if addresses are provided. + 'sendEmail' => 0, +// Optional +// You can specify any custom message to send to your customers in their confirmation e-mail here +// The field can contain HTML if you wish, and be different for each order. This field is optional + 'emailMessage' => '', +// Optional setting. Set this to the mail address which will receive order confirmations and failures + 'vendorEmail' => '', +// Optional parameter, this value will be used to set the BillingAgreement field in the registration POST +// A default is value of 0 is used if this parameter is not included in this properties file + 'billingAgreement' => 1, +// Mandatory parameter, salt used for hashing the password in the local database +// i.e. value: q8W#e1_ + 'customerPasswordSalt' => '', +// Optional parameter, set this to true to use colon delimited format for the basket instead of XML +// Note: The 'Trips' details on the 'Extra Information' page will not be displayed if this flag is set to true. + 'basketAsXmlDisable' => false, +// Set this to true if you want to store all logs in debug.log file + 'logError' => true, +// Optional +// The language the customer sees the payment pages in is determined by the code sent here. If this is NULL then the language default of the shoppers browser will be used. +// If the language is not supported then the language supported in the templates will be used +// Currently supported languages in the Default templates are : +// French, German, Spanish, Portuguese, Dutch and English + 'language' => null, +// Optional parameter reference to the website this transaction came from. This field is useful if transactions can originate from more than one website. Supplying this information will enable reporting to be performed by website. + 'website' => '', + 'requestTimeout' => 30, + 'caCertPath' => '', +); diff --git a/src/Sagepay/constants.php b/src/Sagepay/constants.php index 3b03c10..99d9346 100755 --- a/src/Sagepay/constants.php +++ b/src/Sagepay/constants.php @@ -1,115 +1,115 @@ - Date: Fri, 11 Mar 2022 13:42:25 +0100 Subject: [PATCH 03/15] Fix to issue with query string not being URL-encoded closes #2 commit 48399616e226016f4debe48e8d04e4efafc1a77d Author: Rob Mills Date: Tue May 5 17:00:13 2015 +0100 --- src/Sagepay/classes/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sagepay/classes/common.php b/src/Sagepay/classes/common.php index bf464d2..5777fa7 100755 --- a/src/Sagepay/classes/common.php +++ b/src/Sagepay/classes/common.php @@ -96,7 +96,7 @@ static public function requestPost($url, $data, $ttl = 30, $caCertPath = '') curl_setopt($curlSession, CURLOPT_URL, $url); curl_setopt($curlSession, CURLOPT_HEADER, 0); curl_setopt($curlSession, CURLOPT_POST, 1); - curl_setopt($curlSession, CURLOPT_POSTFIELDS, SagepayUtil::arrayToQueryString($data)); + curl_setopt($curlSession, CURLOPT_POSTFIELDS, SagepayUtil::arrayToQueryString($data,'&',true)); curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curlSession, CURLOPT_TIMEOUT, $ttl); curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 2); From d41332d6e8fdee0fa1dea48b1be7ffb1d175d300 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 13:46:03 +0100 Subject: [PATCH 04/15] discounts now applied to total amount calculation as per #1 commit ffa5e275b063f3282cc3d8871513d0a6a4431555 Author: Rob Mills Date: Tue May 5 17:17:13 2015 +0100 --- src/Sagepay/classes/basket.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Sagepay/classes/basket.php b/src/Sagepay/classes/basket.php index e247b58..dfad71a 100755 --- a/src/Sagepay/classes/basket.php +++ b/src/Sagepay/classes/basket.php @@ -321,6 +321,21 @@ public function getDeliveryGrossAmount() return $this->_deliveryNetAmount + $this->_deliveryTaxAmount; } + /** + * Calculate total value of discounts + * @return int + */ + private function getDiscountAmount() + { + $discountAmount = 0; + if( is_array($this->_discounts) && count($this->_discounts) > 0){ + foreach($this->_discounts as $discount){ + $discountAmount += $discount['fixed']; + } + } + return $discountAmount; + } + /** * Get list of discounts * @@ -533,6 +548,7 @@ public function getAmount() { $amount += $item->getTotalGrossAmount(); } + $amount -= $this->getDiscountAmount(); return $amount; } From cd70c74a2f79f4c5b0d22cfd961acfeb87c459d2 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 13:48:35 +0100 Subject: [PATCH 05/15] fixed return types in doc blocks commit 1207938a220ad05a202890a0ae9491c990756482 Author: Rob Mills Date: Mon May 11 11:45:18 2015 +0100 --- src/Sagepay/classes/basket.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Sagepay/classes/basket.php b/src/Sagepay/classes/basket.php index dfad71a..8c26a3d 100755 --- a/src/Sagepay/classes/basket.php +++ b/src/Sagepay/classes/basket.php @@ -274,7 +274,7 @@ public function addItem(SagepayItem $item) /** * Get delivery net amount * - * @return type + * @return float */ public function getDeliveryNetAmount() { @@ -571,7 +571,7 @@ public function exportAsXml($asXml = true) /** * Export as string with Sagepay specific format * - * @return type + * @return string */ private function _serialize() { From 89d97e5ad88ebdb1910dc77f10c9a37daa40e94a Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 13:49:47 +0100 Subject: [PATCH 06/15] Allow an override total in case of miscalculations closes #1 commit f6de8f885fafb08ac4ed67c9aa074e3ad9261ff7 Author: Rob Mills Date: Thu May 7 16:54:39 2015 +0100 --- src/Sagepay/classes/basket.php | 26 ++++++++++++++++++++++++++ src/Sagepay/classes/common.php | 13 ++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Sagepay/classes/basket.php b/src/Sagepay/classes/basket.php index 8c26a3d..5436390 100755 --- a/src/Sagepay/classes/basket.php +++ b/src/Sagepay/classes/basket.php @@ -68,6 +68,12 @@ class SagepayBasket */ private $_discounts = array(); + /** + * Value used to check basket calculation matches Total + * @var float + */ + private $_overrideAmount = null; + /** * The ship customer ID * @@ -552,6 +558,26 @@ public function getAmount() return $amount; } + + /** + * Set correct Total Amount + * @param $amount + */ + public function setOverrideAmount($amount) + { + $this->_overrideAmount = $amount; + } + + /** + * Set correct Total Amount + * @return float + */ + public function getOverrideAmount() + { + return $this->_overrideAmount; + } + + /** * Return xml structured or serialized string depends on $asXml * diff --git a/src/Sagepay/classes/common.php b/src/Sagepay/classes/common.php index 5777fa7..0065502 100755 --- a/src/Sagepay/classes/common.php +++ b/src/Sagepay/classes/common.php @@ -224,7 +224,18 @@ static public function encryptedOrder(SagepayAbstractApi $request) { $query['Basket'] = $basket->exportAsXml(false); } - + + /** + * This code will catch instances where the basket has been wrongly calculated according + * to the host shopping basket. This fallback stops an incorrect basket being sent to + * Sagepay and guarantees the correct total is paid according to the host basket + */ + if ( $basket->getOverrideAmount() !== null ) { + $query['BasketXML'] = ""; + $query['Basket'] = ""; + $query['Amount'] = number_format($basket->getOverrideAmount(), 2, '.', ''); + } + if (count($settings->getSurcharges()) > 0) { $surcharges = new SagepaySurcharge(); From d3c1196eb072aa00fc27d3c5b3916d399ff93c52 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 13:50:27 +0100 Subject: [PATCH 07/15] prevent invalid basket being sent commit 8d5f5040832f4255eda6822ff703aadf4717a0cb Author: Rob Mills Date: Mon May 11 12:40:13 2015 +0100 --- src/Sagepay/classes/common.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Sagepay/classes/common.php b/src/Sagepay/classes/common.php index 0065502..69f8861 100755 --- a/src/Sagepay/classes/common.php +++ b/src/Sagepay/classes/common.php @@ -218,7 +218,15 @@ static public function encryptedOrder(SagepayAbstractApi $request) // Check if we need to encode cart. if (!$settings->basketAsXmlDisabled()) { - $query['BasketXML'] = $basket->exportAsXml(); + /** + * need to make sure the basket XML is less than 20000 characters + * if it's too long we can't send it + */ + $basketExport = $basket->exportAsXml(); + if(strlen($basketExport) > 20000){ + $basketExport = ""; + } + $query['BasketXML'] = $basketExport; } else { From d98e44cb6402bb75e15552737209bb625e15a709 Mon Sep 17 00:00:00 2001 From: ekes Date: Wed, 9 Mar 2022 16:15:43 +0100 Subject: [PATCH 08/15] Escape strings to prevent XML node errors. Mainly if you put a & into createElement it throws a fatal. --- src/Sagepay/classes/item.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Sagepay/classes/item.php b/src/Sagepay/classes/item.php index 4392f73..b2dead7 100755 --- a/src/Sagepay/classes/item.php +++ b/src/Sagepay/classes/item.php @@ -608,9 +608,13 @@ public function asDomElement(DOMDocument $basket) $value = $this->$getter(); $node = null; - if (is_string($value) || is_int($value)) + if (is_string($value)) { - $node = $basket->createElement($name, trim($value)); + $node = $basket->createElement($name); + $node->appendChild($basket->createTextNode(trim($value))); + } + else if (is_int($value)) { + $node = $basket->createElement($name, $value); } else if (is_float($value)) { From 0fa838c292b95be392876114c8d26b116686cd86 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 15:02:13 +0100 Subject: [PATCH 09/15] Escape all strings going into XML. --- src/Sagepay/classes/basket.php | 9 +++++++-- src/Sagepay/classes/customer.php | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Sagepay/classes/basket.php b/src/Sagepay/classes/basket.php index 5436390..1a3fe3c 100755 --- a/src/Sagepay/classes/basket.php +++ b/src/Sagepay/classes/basket.php @@ -686,9 +686,14 @@ private function _createDomNode($dom, $value, $name = null) { return $dom->createElement($value); } - else if (is_string($value) || is_int($value)) + else if (is_string($value)) { - return $dom->createElement($name, trim($value)); + $node = $dom->createElement($name); + return $node->appendChild($dom->createTextNode(trim($value))); + } + else if (is_int($value)) + { + return $dom->createElement($name, $value); } else if (is_float($value)) { diff --git a/src/Sagepay/classes/customer.php b/src/Sagepay/classes/customer.php index da15c24..33d127a 100755 --- a/src/Sagepay/classes/customer.php +++ b/src/Sagepay/classes/customer.php @@ -275,7 +275,8 @@ public function export() { continue; } - $node = $dom->createElement($field, $value); + $node = $dom->createElement($field); + $node->appendChild($dom->createTextNode(trim($value))); $dom->documentElement->appendChild($node); } return $dom->saveXML($dom->documentElement); From 421c1e83be43fc1b8c05595daa4cfc3c1fd717dc Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 15:43:03 +0100 Subject: [PATCH 10/15] Only allow A-Z a-z 0-9 - in SKUs. --- src/Plugin/Commerce/PaymentGateway/SagepayCommon.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php b/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php index e210f27..4709ad0 100644 --- a/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php +++ b/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php @@ -174,7 +174,10 @@ protected function getBasketFromProducts(OrderInterface $order) { $basketItem = new SagepayItem(); $basketItem->setDescription($item->label()); $basketItem->setProductCode($product->id()); - $basketItem->setProductSku(substr($product->getSku(), 0, 12)); + # Can't find documentation of characters it doesn't like in a SKU but + # there seem to be plenty so this is pretty extreme. + $sku = preg_replace('/[^a-z0-9]+/i', '-', substr($product->getSku(), 0, 12)); + $basketItem->setProductSku($sku); $basketItem->setQuantity($item->getQuantity()); $basketItem->setUnitNetAmount($net); $basketItem->setUnitTaxAmount($tax); From 8d404d5c447991c12a48115aaaba775939d65cb2 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 18:16:44 +0100 Subject: [PATCH 11/15] A late in the day fix to export the discounts in the XML basket. --- .../Commerce/PaymentGateway/FormIntegration.php | 13 +++++++++++-- src/Sagepay/classes/basket.php | 16 +++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php index 2ed7929..81fdfeb 100644 --- a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php +++ b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php @@ -295,7 +295,6 @@ private function decryptSagepayResponse($formPassword, $encryptedResponse) { public function buildTransaction(PaymentInterface $payment) { /** @var OrderInterface $order */ $order = $payment->getOrder(); - $sagepayFormApi = $this->getSagepayApi($order); if (!$basket = $this->getBasketFromProducts($order)) { @@ -307,14 +306,25 @@ public function buildTransaction(PaymentInterface $payment) { $sagepayFormApi->addAddress($this->getBillingAddress($order)); + $discounts = []; $taxAmount = 0; if ($adjustments = $order->getAdjustments()) { foreach ($adjustments as $adjustment) { if ($adjustment->getType() == 'tax') { $taxAmount += (float) $adjustment->getAmount()->getNumber(); } + elseif (!$adjustment->isIncluded() && $adjustment->getAmount()->isNegative()) { + $discounts[] = [ + 'fixed' => (float) abs($adjustment->getAmount()->getNumber()), + 'description' => $adjustment->getLabel(), + ]; + } } } + $basket->setDeliveryTaxAmount($taxAmount); + if (count($discounts)) { + $basket->setDiscounts($discounts); + } if ($this->moduleHandler->moduleExists('commerce_shipping')) { /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface[] $shipments */ @@ -329,7 +339,6 @@ public function buildTransaction(PaymentInterface $payment) { } } $basket->setDeliveryNetAmount($delivery); - $basket->setDeliveryTaxAmount($taxAmount); } $request = $sagepayFormApi->createRequest(); diff --git a/src/Sagepay/classes/basket.php b/src/Sagepay/classes/basket.php index 1a3fe3c..b07f173 100755 --- a/src/Sagepay/classes/basket.php +++ b/src/Sagepay/classes/basket.php @@ -329,7 +329,7 @@ public function getDeliveryGrossAmount() /** * Calculate total value of discounts - * @return int + * @return float */ private function getDiscountAmount() { @@ -686,6 +686,20 @@ private function _createDomNode($dom, $value, $name = null) { return $dom->createElement($value); } + else if ($name == 'discounts') { + // This should be another class like SagepayItem, but this is simple + // and quick. + $discounts = $dom->createElement('discounts'); + foreach ($value as $discount) { + $node = $dom->createElement('discount'); + $node->appendChild($dom->createElement('fixed', number_format($discount['fixed'], 2, '.', ''))); + $description = $dom->createElement('description'); + $description->appendChild($dom->createTextNode(trim($discount['description']))); + $node->appendChild($description); + $discounts->appendChild($node); + } + return $discounts; + } else if (is_string($value)) { $node = $dom->createElement($name); From 9f7b44f2cdebb1a2a4dd1ab3e51625c15ac53a0f Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 18:16:44 +0100 Subject: [PATCH 12/15] A late in the day fix to export the discounts in the XML basket. --- src/Plugin/Commerce/PaymentGateway/FormIntegration.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php index 81fdfeb..1a01358 100644 --- a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php +++ b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php @@ -314,6 +314,8 @@ public function buildTransaction(PaymentInterface $payment) { $taxAmount += (float) $adjustment->getAmount()->getNumber(); } elseif (!$adjustment->isIncluded() && $adjustment->getAmount()->isNegative()) { + // Label might not be unique. Need an associative array. Add the + // count. $discounts[] = [ 'fixed' => (float) abs($adjustment->getAmount()->getNumber()), 'description' => $adjustment->getLabel(), From 5edd6300be2be64748ebf9fc1b4e9bae6b335cb2 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 11 Mar 2022 20:07:20 +0100 Subject: [PATCH 13/15] Add a check for correct price. If for whatever reason the basket doesn't get the correct total, trust the total from commerce. The checkout won't have the order details, but will have the commerce total to bill. --- .../Commerce/PaymentGateway/FormIntegration.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php index 1a01358..42255a6 100644 --- a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php +++ b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php @@ -343,6 +343,18 @@ public function buildTransaction(PaymentInterface $payment) { $basket->setDeliveryNetAmount($delivery); } + // Sanity check. If the basket total isn't correct override it and log it. + if ($order->getTotalPrice()->getNumber() != (string) $basket->getAmount()) { + $basket->setOverrideAmount((float) $order->getTotalPrice()->getNumber()); + $this->loggerChannelFactory->get('commerce_sagepay')->error( + 'Order id @id basket total was @basket instead of @total', [ + '@id' => $order->id(), + '@basket' => $basket->getAmount(), + '@total' => $order->getTotalPrice()->getNumber(), + ] + ); + } + $request = $sagepayFormApi->createRequest(); $order->setData('sagepay_form', [ From 322b414ff3c63d6dc3eb9a104cd53599e1b6ce18 Mon Sep 17 00:00:00 2001 From: ekes Date: Fri, 18 Mar 2022 13:52:10 +0100 Subject: [PATCH 14/15] Send the order number if set, or id if not, within the VendorTxId. --- src/Plugin/Commerce/PaymentGateway/FormIntegration.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php index 42255a6..4187a6b 100644 --- a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php +++ b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php @@ -302,6 +302,7 @@ public function buildTransaction(PaymentInterface $payment) { } $basket->setDescription($this->configuration['sagepay_order_description']); + $basket->setId($order->getOrderNumber() ?? $order->id()); $sagepayFormApi->setBasket($basket); $sagepayFormApi->addAddress($this->getBillingAddress($order)); From 1875ed453c7e4ec1383744411d86f2b0789b4eeb Mon Sep 17 00:00:00 2001 From: ekes Date: Mon, 21 Mar 2022 19:30:16 +0100 Subject: [PATCH 15/15] Handle failure return messaging. --- .../PaymentGateway/FormIntegration.php | 20 ++++++++++++++++++- .../Commerce/PaymentGateway/SagepayCommon.php | 18 ++++++++--------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php index 4187a6b..6e4061e 100644 --- a/src/Plugin/Commerce/PaymentGateway/FormIntegration.php +++ b/src/Plugin/Commerce/PaymentGateway/FormIntegration.php @@ -241,11 +241,29 @@ public function onReturn(OrderInterface $order, Request $request) { $logContext = $sagepayError['logContext']; $this->loggerChannelFactory->get('commerce_sagepay') ->log($logLevel, $logMessage, $logContext); - \Drupal::messenger()->{$sagepayError['drupalMessageType']}($sagepayError['drupalMessage']); + $this->messenger()->addMessage($sagepayError['drupalMessage'], $sagepayError['drupalMessageType']); throw new PaymentGatewayException('ERROR result from Sagepay for order ' . $decryptedSagepayResponse['VendorTxCode']); } } + /** + * {@inheritdoc} + */ + public function onCancel(OrderInterface $order, Request $request) { + $formPassword = $this->getMode() == SAGEPAY_ENV_LIVE ? $this->configuration['enc_key'] : $this->configuration['test_enc_key']; + $decryptedSagepayResponse = $this->decryptSagepayResponse($formPassword, $this->requestStack->getCurrentRequest()->query->get('crypt')); + $sagepayError = $this->decipherSagepayError($order, $decryptedSagepayResponse); + $logLevel = $sagepayError['logLevel']; + $logMessage = $sagepayError['logMessage']; + $logContext = $sagepayError['logContext']; + $this->loggerChannelFactory->get('commerce_sagepay') + ->log($logLevel, $logMessage, $logContext); + $this->messenger()->addMessage($sagepayError['drupalMessage'], $sagepayError['drupalMessageType']); + $this->messenger()->addMessage($this->t('If you canceled checkout at @gateway you may resume the checkout process here when you are ready. If you didn\'t cancel payment, there was an error taking payment with the provider. Please try later or contact us.', [ + '@gateway' => $this->getDisplayLabel(), + ])); + } + /** * Create a Commerce Payment from a Sagepay form request successful result. * diff --git a/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php b/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php index 4709ad0..cbe97ec 100644 --- a/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php +++ b/src/Plugin/Commerce/PaymentGateway/SagepayCommon.php @@ -204,13 +204,13 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag switch ($decryptedSagepayResponse['Status']) { case 'ABORT': $logLevel = 'alert'; - $logMessage = 'ABORT error from SagePay for order %order_id with message %msg'; + $logMessage = 'ABORT response from SagePay for order %order_id with message %msg'; $logContext = [ '%order_id' => $order->id(), '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; - $drupalMessage = $this->t('Your SagePay transaction was aborted.'); - $drupalMessageType = 'addError'; + $drupalMessage = $this->t('Your SagePay transaction was cancelled.'); + $drupalMessageType = 'warning'; break; case 'NOTAUTHED': @@ -221,7 +221,7 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; $drupalMessage = $this->t('Your transaction was not authorised by SagePay.'); - $drupalMessageType = 'addError'; + $drupalMessageType = 'error'; break; case 'REJECTED': @@ -232,7 +232,7 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; $drupalMessage = $this->t('Your transaction was rejected by SagePay.'); - $drupalMessageType = 'addError'; + $drupalMessageType = 'error'; break; case 'MALFORMED': @@ -243,7 +243,7 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; $drupalMessage = $this->t('Sorry the transaction has failed.'); - $drupalMessageType = 'addError'; + $drupalMessageType = 'error'; break; case 'INVALID': @@ -254,7 +254,7 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; $drupalMessage = $this->t('Sorry the transaction has failed.'); - $drupalMessageType = 'addError'; + $drupalMessageType = 'error'; break; case 'ERROR': @@ -266,7 +266,7 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; $drupalMessage = $this->t('Sorry an error occurred while processing your transaction.'); - $drupalMessageType = 'addError'; + $drupalMessageType = 'error'; break; @@ -278,7 +278,7 @@ private function decipherSagepayError(OrderInterface $order, array $decryptedSag '%msg' => $decryptedSagepayResponse['StatusDetail'], ]; $drupalMessage = $this->t('Sorry an error occurred while processing your transaction.'); - $drupalMessageType = 'addError'; + $drupalMessageType = 'error'; } return [