diff --git a/README.md b/README.md index 2aaff4d..c174029 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,14 @@ The following gateways are provided by this package: For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay) repository. +### Basket format + +Sagepay currently supports two different formats for sending cart/item information to them: + - [BasketXML](http://www.sagepay.co.uk/support/12/36/protocol-3-00-basket-xml) + - [Basket](http://www.sagepay.co.uk/support/error-codes/3021-invalid-basket-format-invalid) + +These are incompatible with each other, and cannot be both sent in the same transaction. *BasketXML* is the most modern format, and is the default used by this driver. *Basket* is an older format which may be deprecated one day, but is also the only format currently supported by some of the Sage accounting products (Line 50, etc) which can pull transaction data directly from Sagepay. Therefore for users who require this type of integration, an optional parameter `useOldBasketFormat` with a value of `true` can be passed in the driver's `initialize()` method. + ## Support If you are having general issues with Omnipay, we suggest posting on diff --git a/src/DirectGateway.php b/src/DirectGateway.php index 028c5a1..de757d1 100644 --- a/src/DirectGateway.php +++ b/src/DirectGateway.php @@ -36,6 +36,18 @@ public function setVendor($value) { return $this->setParameter('vendor', $value); } + + public function setUseOldBasketFormat($value) + { + $value = (bool)$value; + + return $this->setParameter('useOldBasketFormat', $value); + } + + public function getUseOldBasketFormat() + { + return $this->getParameter('useOldBasketFormat'); + } // Access to the HTTP client for debugging. // NOTE: this is likely to be removed or replaced with something diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php index 192cbb2..dd611a0 100644 --- a/src/Message/AbstractRequest.php +++ b/src/Message/AbstractRequest.php @@ -26,6 +26,18 @@ public function getService() { return $this->action; } + + public function setUseOldBasketFormat($value) + { + $value = (bool)$value; + + return $this->setParameter('useOldBasketFormat', $value); + } + + public function getUseOldBasketFormat() + { + return $this->getParameter('useOldBasketFormat'); + } public function getAccountType() { @@ -233,4 +245,44 @@ protected function getItemData() return $result; } + + /** + * Generate Basket string in the old format + * This is called if "useOldBasketFormat" is set to true in the gateway config + * @return string Basket field in format of: + * 1:Item:2:10.00:0.00:10.00:20.00 + * [number of lines]:[item name]:[quantity]:[unit cost]:[item tax]:[item total]:[line total] + */ + protected function getItemDataNonXML() + { + + $result = ''; + $items = $this->getItems(); + $count = 0; + + foreach ($items as $basketItem) { + $lineTotal = ($basketItem->getQuantity() * $basketItem->getPrice()); + + $description = $this->filterItemName($basketItem->getName()); + $description = str_replace(':', ' ', $description); // Make sure there aren't any colons in the name + // Perhaps : should be replaced with '-' or other symbol? + + $result .= ':' . $description . // Item name + ':' . $basketItem->getQuantity() . // Quantity + ':' . number_format($basketItem->getPrice(), 2, '.', '') . // Unit cost (without tax) + ':0.00' . // Item tax + ':' . number_format($basketItem->getPrice(), 2, '.', '') . // Item total + ':' . number_format($lineTotal, 2, '.', ''); // Line total + // As the getItemData() puts 0.00 into tax, same was done here + + $count++; + + } + + // Prepend number of lines to the result string + $result = $count . $result; + + return $result; + + } } diff --git a/src/Message/DirectAuthorizeRequest.php b/src/Message/DirectAuthorizeRequest.php index 0007ef4..76ee316 100644 --- a/src/Message/DirectAuthorizeRequest.php +++ b/src/Message/DirectAuthorizeRequest.php @@ -54,9 +54,16 @@ protected function getBaseAuthorizeData() $data['DeliveryPhone'] = $card->getShippingPhone(); $data['CustomerEMail'] = $card->getEmail(); - $basketXML = $this->getItemData(); - if (!empty($basketXML)) { - $data['BasketXML'] = $basketXML; + if ($this->getUseOldBasketFormat()) { + $basket = $this->getItemDataNonXML(); + if (!empty($basket)) { + $data['Basket'] = $basket; + } + } else { + $basketXML = $this->getItemData(); + if (!empty($basketXML)) { + $data['BasketXML'] = $basketXML; + } } return $data;