2015-03-31 2 views
1

Я изо всех сил стараюсь работать, и Omnipay не поставляется с большой документацией. Я успешно использовал его для других платежных шлюзов, но не с Sagepay. Я пытаюсь интегрировать его в CodeIgniter, но могу работать с примерами в других рамках - я отчаянно бегу!У кого-нибудь есть рабочий пример Omnipay и Sagepay Server или Sagepay Direct (с 3D Secure)?

+0

Просто выяснилось, что симулятор больше не поддерживается, и это то, что я использовал для тестирования. Я еще не знаю, если это причина моих проблем, так как теперь приходится настраивать партнерскую учетную запись для тестирования, но я думал, что обновляю ее, если кто-то еще столкнется с этим. – JoJo

+0

Существует также тема, касающаяся протоколов Sagepay 3 и Omnipay здесь https://github.com/thephpleague/omnipay-sagepay/issues/19 – JoJo

+0

Эта тема поставила меня на правильный путь: https://github.com/thephpleague/omnipay/issues/255 – JoJo

ответ

1

Благодаря большой помощи в github (см. Комментарии в моем исходном посте для ссылки на поток), теперь у меня есть рабочий код, который я поделюсь здесь, если он поможет кому-то еще в будущем.

<?php 

use Omnipay\Omnipay; 

class PaymentGateway { 

    //live details 
    private $live_vendor = 'xxx'; 
    //test details 
    private $test_vendor= 'xxx'; 

    //payment settings 
    private $testMode = true; 
    private $api_vendor = ''; 
    private $gateway = null; 

    public function __construct() 
    { 
     parent::__construct(); 
     //setup api details for test or live 
     if ($this->testMode) : 
      $this->api_vendor = $this->test_vendor; 
     else : 
      $this->api_vendor = $this->live_vendor; 
     endif; 

     //initialise the payment gateway 
     $this->gateway = Omnipay::create('SagePay_Server'); 
     $this->gateway->setVendor($this->api_vendor); 
     $this->gateway->setTestMode($this->testMode); 



    } 


    public function initiate() 
    { 

     //get order details 
     $orderNo = customFunctionToGetOrderNo(); //get the order number from your system however you store and retrieve it 

     $params = array(
      'description'=> 'Online order', 
      'currency'=> 'GBP', 
      'transactionId'=> $orderNo, 
      'amount'=> customFunctionToGetOrderTotal($orderNo) 
     ); 


     $customer = customFunctionToGetCustomerDetails($orderNo); 

     $params['returnUrl'] = '/payment-gateway-process/' . $orderNo . '/'; //this is the Sagepay NotificationURL 

     $params['card'] = array(
      'firstName' => $customer['billing_firstname'], 
      'lastName' => $customer['billing_lastname'], 
      'email' => $customer['billing_email'], 
      'billingAddress1' => $customer['billing_address1'], 
      'billingAddress2' => $customer['billing_address2'], 
      'billingCity' => $customer['billing_town'], 
      'billingPostcode' => $customer['billing_postcode'], 
      'billingCountry' => $customer['billing_country'], 
      'billingPhone' => $customer['billing_telephone'], 
      'shippingAddress1' => $customer['delivery_address1'], 
      'shippingAddress2' => $customer['delivery_address2'], 
      'shippingCity' => $customer['delivery_town'], 
      'shippingPostcode' => $customer['delivery_postcode'], 
      'shippingCountry' => $customer['delivery_country'] 
     ); 


     try { 
      $response = $this->gateway->purchase($params)->send(); 


      if ($response->isSuccessful()) : 

       //not using this part 

      elseif ($response->isRedirect()) : 

       $reference = $response->getTransactionReference(); 
       customFunctionToSaveTransactionReference($orderNo, $reference); 
       $response->redirect(); 

      else : 
       //do something with an error 
       echo $response->getMessage(); 

      endif; 

     } catch (\Exception $e) { 

      //do something with this if an error has occurred 
      echo 'Sorry, there was an error processing your payment. Please try again later.'; 
     } 



    } 


    public function processPayment($orderNo) 
    { 

     $params = array(
      'description'=> 'Online order', 
      'currency'=> 'GBP', 
      'transactionId'=> $orderNo, 
      'amount'=> customFunctionToGetOrderTotal($orderNo) 
     ); 

     $customer = customFunctionToGetCustomerDetails($orderNo); 


     $transactionReference = customFunctionToGetTransactionReference($orderNo); 


     try { 
      $response = $this->gateway->completePurchase(array(
       'transactionId' => $orderNo, 
       'transactionReference' => $transactionReference, 
      ))->send(); 

      customFunctionToSaveStatus($orderNo, array('payment_status' => $response->getStatus())); 
      customFunctionToSaveMessage($orderNo, array('gateway_response' => $response->getMessage())); 

      //encrypt it to stop anyone being able to view other orders 
      $encodeOrderNo = customFunctionToEncodeOrderNo($orderNo); 
      $response->confirm('/payment-gateway-response/' . $encodeOrderNo); 

     } catch(InvalidResponseException $e) { 
      // Send "INVALID" response back to SagePay. 
      $request = $this->gateway->completePurchase(array()); 
      $response = new \Omnipay\SagePay\Message\ServerCompleteAuthorizeResponse($request, array()); 

      customFunctionToSaveStatus($orderNo, array('payment_status' => $response->getStatus())); 
      customFunctionToSaveMessage($orderNo, array('gateway_response' => $response->getMessage())); 

      redirect('/payment-error-response/'); 
     } 



    } 


    public function paymentResponse($encodedOrderNo) 
    { 
     $orderNo = customFunctionToDecode($encodedOrderNo); 
     $sessionOrderNo = customFunctionToGetOrderNo(); 
     if ($orderNo != $sessionOrderNo) : 
      //do something here as someone is trying to fake a successful order 
     endif; 
     $status = customFunctionToGetOrderStatus($orderNo); 

     switch(strtolower($status)) : 
      case 'ok' : 
       customFunctionToHandleSuccess($orderNo); 
      break; 

      case 'rejected' : 
      case 'notauthed' : 
       //do something to handle failed payments 
      break; 

      case 'error' : 
       //do something to handle errors 

      break; 

      default: 

       //do something if it ever reaches here 

     endswitch; 


    } 

} 
+0

Я вижу, что номер заказа зашифрован в обратном URL. Другой способ - не предоставлять какие-либо параметры этого URL-адреса, а полагаться на orderNo, которые были сохранены в сеансе до вызова обработчика уведомлений. «Переадресация» на ошибку также неверна - здесь не будет перенаправлено. Вы должны вызывать ошибку '$ response-> ('ваш url', 'ваше необязательное сообщение'); вместо этого вы вернете URL-адрес SagePay, который затем отправит пользователя на этот URL-адрес для вас. – Jason

1

Я дал разговор вчера вечером об этом, и поставили рабочие демо-скрипты на GitHub здесь:

https://github.com/academe/OmniPay-SagePay-Demo

SagePay Direct является одноразовым действием - OmniPay посылает детали сделки и получает немедленный ответ.

SagePay Server включает перенаправление пользователя на сайт SagePay для авторизации транзакции с использованием данных своей карты. Этот API использует уведомление, в котором SagePay будет вызывать ваше приложение напрямую с результатами авторизации. Это происходит за пределами сеанса пользователя, поэтому требуется, чтобы транзакция хранилась в базе данных, чтобы она могла быть разделена между двумя транзакциями.

Все это в приведенных выше сценариях. authorize.php выполнит авторизацию. Отредактируйте это, чтобы использовать SagePay\Direct или SagePay\Server, чтобы увидеть, как это работает. Обработчик уведомлений для SagePay\Server - sagepay-confirm.php и который в конечном итоге отправляет пользователя в final.php, где результат может быть прочитан из транзакции, хранящейся в базе данных.

Сценарии прокомментированы и должны иметь смысл, но не стесняйтесь задавать больше вопросов о них здесь или в контролере ошибок этого хранилища github.

Я не пробовал SagePay\Direct с 3D-Secure, хотя. Для поддержки скриптов может потребоваться некоторая модификация, предполагая, что комбинация вещь.

Смежные вопросы