Я изо всех сил пытаюсь заставить работать любой из них, а в Omnipay не так много документации. Я успешно использовал его для других платежных шлюзов, но не для Sagepay. Я пытаюсь интегрировать его в CodeIgniter, но могу работать с примерами в других фреймворках — я уже в отчаянии!
У кого-нибудь есть рабочий пример Omnipay и Sagepay Server или Sagepay Direct (с 3D Secure)?
Ответы (2)
Благодаря отличной помощи на 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;
}
}
$response->error('your url', 'your optional message');
, и это вернет URL-адрес SagePay, который затем отправит пользователя на этот URL-адрес для вас.
- person Jason; 07.07.2015
Вчера вечером я говорил об этом и разместил рабочие демо-скрипты на github здесь:
https://github.com/academe/OmniPay-SagePay-Demo
SagePay Direct — это разовое действие: OmniPay отправляет детали транзакции и получает немедленный ответ.
Сервер SagePay включает перенаправление пользователя на веб-сайт SagePay для авторизации транзакции с использованием данных его карты. Этот API использует уведомляющее сообщение, в котором SagePay напрямую вызывает ваше приложение с результатами авторизации. Это происходит за пределами сеанса пользователя, поэтому требуется, чтобы транзакция сохранялась в базе данных, чтобы ее можно было разделить между двумя транзакциями.
Все это есть в скриптах по ссылкам выше. authorize.php
выполнит авторизацию. Отредактируйте это, чтобы использовать SagePay\Direct
или SagePay\Server
, чтобы увидеть, как это работает. Обработчик уведомлений для SagePay\Server
— это sagepay-confirm.php
, который в конечном итоге отправляет пользователя в final.php
, где результат может быть прочитан из транзакции, хранящейся в базе данных.
Все сценарии прокомментированы и должны иметь смысл, но не стесняйтесь задавать дополнительные вопросы о них здесь или в системе отслеживания проблем этого репозитория github.
Однако я не пробовал SagePay\Direct
с 3D-Secure. Сценарии могут нуждаться в некоторой модификации для поддержки этого, если предположить, что эта комбинация вещь.