/** * Initialises a payment for the supplied payment transaction using SagePay. * Returns a URL to redirect the user to (normally a hosted payment form). * * @param PaymentTransaction $paymentTransaction The payment transaction we've created * @return string The URL to forward the user to */ public static function initialisePayment($paymentTransaction) { if ($paymentTransaction->status == 'ptsSubmitted') { return $paymentTransaction->initialResponse->NextURL; } // Generate a unique TX code $cart = $paymentTransaction->cart; $user = User::find_by_id($cart->user_id); $gateway = $paymentTransaction->paymentgateway; $paymentTransaction->sender = $user->email; // We need to build the basket data $basket = ''; $count = 0; // Item Discounts foreach ($cart->items() as $item) { $count++; $amount = self::formatMoney($item->initial_cost()); $desc = str_replace(':', '', $item->description); $basket .= ":{$desc}:1:::{$amount}:{$amount}"; if ($item->discount->id) { $item->discount->reload(); $count++; if ($item->discount->discount->type == "percentage") { $amount = self::formatMoney($item->discount->discount->calculate_saving($item->initial_cost())); } else { $amount = self::formatMoney($item->discount->discount->value); } $desc = str_replace(':', '', "{$item->discount->discount->code}) {$item->discount->discount->description}"); $basket .= ":{$desc}:1:::-{$amount}:-{$amount}"; } } // Full Cart Discounts if ($cart->full_cart_discount()) { foreach ($cart->discounts(true) as $discount) { if ($discount->cart_item_id) { continue; } $count++; if ($discount->discount->type == "percentage") { $amount = self::formatMoney($discount->discount->calculate_saving($cart->cost(0, 1))); } else { $amount = self::formatMoney($discount->discount->value); } $desc = str_replace(':', '', "Discount ({$discount->discount->code}) {$discount->discount->description}"); $basket .= ":{$desc}:1:::-{$amount}:-{$amount}"; } } $basket = "{$count}{$basket}"; // Prepare our parameters $params = array('VPSProtocol' => '3.00', 'TxType' => 'PAYMENT', 'Vendor' => $gateway->getSetting('vendor'), 'VendorTxCode' => $paymentTransaction->id, 'Amount' => $paymentTransaction->getFormattedAmount(), 'Currency' => 'GBP', 'Description' => "epic.LAN Cart {$cart->id}", 'NotificationURL' => $gateway->getSetting('notificationurl'), 'BillingSurname' => $user->surname, 'BillingFirstnames' => $user->firstname, 'BillingAddress1' => $user->address1, 'BillingAddress2' => $user->address2, 'BillingCity' => $user->towncity, 'BillingPostCode' => $user->postcode, 'BillingCountry' => strtoupper($user->country->code), 'DeliverySurname' => $user->surname, 'DeliveryFirstnames' => $user->firstname, 'DeliveryAddress1' => $user->address1, 'DeliveryAddress2' => $user->address2, 'DeliveryCity' => $user->towncity, 'DeliveryPostCode' => $user->postcode, 'DeliveryCountry' => strtoupper($user->country->code), 'Basket' => $basket); if (strtoupper($user->country->code) == 'US') { $params['BillingState'] = $user->county; $params['DeliveryState'] = $user->county; } // Make our request $url = $gateway->getSetting('endpoint'); $output = self::httpPost($url, $params); // Parse the response $lines = explode("\r\n", $output); $response = new stdClass(); foreach ($lines as $line) { $line = explode('=', $line); $key = array_shift($line); $response->{$key} = implode('=', $line); } if (property_exists($response, 'VPSTxId')) { $paymentTransaction->externalid = $response->VPSTxId; } $paymentTransaction->initialResponse = $response; if ($response->Status == 'OK') { $paymentTransaction->status = 'ptsSubmitted'; $paymentTransaction->save(); return $response->NextURL; } $paymentTransaction->failurereason = $response->StatusDetail; $paymentTransaction->status = 'ptsFailed'; $paymentTransaction->save(); throw new PGI_Exception('Unable to establish payment session'); }