Подключать будем обычную одностадийную оплату без возможности возврата средств (это, возможно, добавлю позже если будет время или заказы). Алгоритм заключается в следующем:
- Клиент заключает договор со Сбером. Ему выдают данные для работы на тестовой среде. Данные, которые нам понадобятся:
- Логин;
- Пароль;
- Api token;
- Ссылка для отправки запросов на тестовой среде. Для всех клиентов она, по сути, одна -
- Набор карт для тестирования с разными статусами работы (с ошибками, с оплатой и т.д.)
- Далее нам необходимо написать скрипт, который будет отправлять запрос Сберу на регистрацию заказа со следующими параметрами:
- token (или логин и пароль, как удобнее. Но используем что-либо одно - либо токен, либо пару логин и пароль, все вместе нельзя, вернется ошибка);
- orderNumber - номер заказа, который генерируется в интернет-магазине. По сути, любое число.
- amount - цена заказа. Здесь необходимо цену умножать на 100 т.к. Сбер все считает в копейках и если, например, стоимость заказа 19 450 руб. то Сбер это поймет как 194 рубля 50 копеек т.е. отодвинет запятую на 2 знака справа;
- returnUrl - адрес возврата клиента после оплаты. Здесь передаем url, например, "http://unreal-stuff.ru/payments/". На этой странице можно разместить информацию об успешной оплате и передать номер заказа.
- Тестируем оплату. Для начала, это можно делать обычными запросами через
curl
, чтобы проверить, что клиент нам предоставил корректные данные. Пример скрипта:
<?php
$data = array(
'userName' => 'testlogin-api',
'password' => 'Password%2a1',
'orderNumber' => '4223',
'amount' => '19450',
'returnUrl' => 'http://unreal-stuff.ru/payments/'
);
$curl = curl_init();
curl_setopt_array($curl,
array(
CURLOPT_URL => 'https://3dsec.sberbank.ru/payment/rest/register.do',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($data)
)
);
$response = curl_exec($curl);
$out = json_decode($response, true);
curl_close($curl);
echo "<pre>";
print_r($out);
echo "</pre>";
Далее, если все хорошо, Сбер отдаст нам массив со следующими данными:
Это означает, что все ок и мы можем редиректить клиента по ссылке, указанной в formUrl
. Как только мы полностью напишем скрипт и он будет редиректить по указанной ссылке то мы будем попадать на такую страницу:
Примечание. Здесь мы не умножили цену на 100, поэтому результат получился такой, каким я описывал его ранее!
На этой странице можно поигратсья с картами и посмотреть на реакцию сервиса на различные карты (в которые зашиты определенные ошибки типа не хватает средств и т.д.) . После проведения оплаты на этой странице, Сбер редиректнет нас на страницу, которую мы указали ранее - http://unreal-stuff.ru/payments/
Перевод на боевую среду заключается лишь в изменении логина, пароля и ссылки для отправки запроса. url должен будет выглядет уже следующим образом:
CURLOPT_URL => 'https://securepayments.sberbank.ru/payment/rest/register.do'
Важно, чтобы клиент, с которым вы работаете, сменил пароль. В моем случае клиент этого не сделал и мне возвращалась 5 ошибка:
Такое происходит в случаях если:
- Не была проведена процедура смены транспортного пароля
Password*1
на постоянный - Происходит обращение с парой логин/пароль, предназначенной для тестовой среды, к боевой среде
Как писать скрипт - личное дело каждого. Все зависит от CMS, с которой вы работаете! Я припиливал этот функционал на modx к уже существующему модулю оплат.
Вот пример скрипта, который дает сам Сбербанк:
<?php
/**
* ДАННЫЕ ДЛЯ ПОДКЛЮЧЕНИЯ К ПЛАТЕЖНОМУ ШЛЮЗУ
*
* USERNAME Логин магазина, полученный при подключении.
* PASSWORD Пароль магазина, полученный при подключении.
* GATEWAY_URL Адрес платежного шлюза.
* RETURN_URL Адрес, на который надо перенаправить пользователя
* в случае успешной оплаты.
*/
define('TOKEN', 'test-tokent')
define('USERNAME', 'test-api');
define('PASSWORD', 'testpass');
define('GATEWAY_URL', 'https://3dsec.sberbank.ru/payment/invoice/index.html?token=' . TOKEN);
define('RETURN_URL', '***');
/**
* ФУНКЦИЯ ДЛЯ ВЗАИМОДЕЙСТВИЯ С ПЛАТЕЖНЫМ ШЛЮЗОМ
*
* Для отправки POST запросов на платежный шлюз используется
* стандартная библиотека cURL.
*
* ПАРАМЕТРЫ
* method Метод из API.
* data Массив данных.
*
* ОТВЕТ
* response Ответ.
*/
function gateway($method, $data) {
$curl = curl_init(); // Инициализируем запрос
curl_setopt_array($curl, array(
CURLOPT_URL => GATEWAY_URL.$method, // Полный адрес метода
CURLOPT_RETURNTRANSFER => true, // Возвращать ответ
CURLOPT_POST => true, // Метод POST
CURLOPT_POSTFIELDS => http_build_query($data) // Данные в запросе
));
$response = curl_exec($curl); // Выполненяем запрос
$response = json_decode($response, true); // Декодируем из JSON в массив
curl_close($curl); // Закрываем соединение
return $response; // Возвращаем ответ
}
/**
* ВЫВОД ФОРМЫ НА ЭКРАН
*/
if ($_SERVER['REQUEST_METHOD'] == 'GET' && !isset($_GET['orderId'])) {
echo '
<form method="post" action="/rest.php">
<label>Order number</label><br />
<input type="text" name="orderNumber" /><br />
<label>Amount</label><br />
<input type="text" name="amount" /><br />
<button type="submit">Submit</button>
</form>
';
}
/**
* ОБРАБОТКА ДАННЫХ ИЗ ФОРМЫ
*/
else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$data = array(
'userName' => USERNAME,
'password' => PASSWORD,
'orderNumber' => urlencode($_POST['orderNumber']),
'amount' => urlencode($_POST['amount']),
'returnUrl' => RETURN_URL
);
/**
* ЗАПРОС РЕГИСТРАЦИИ ОДНОСТАДИЙНОГО ПЛАТЕЖА В ПЛАТЕЖНОМ ШЛЮЗЕ
* register.do
*
* ПАРАМЕТРЫ
* userName Логин магазина.
* password Пароль магазина.
* orderNumber Уникальный идентификатор заказа в магазине.
* amount Сумма заказа.
* returnUrl Адрес, на который надо перенаправить пользователя в случае успешной оплаты.
*
* ОТВЕТ
* В случае ошибки:
* errorCode Код ошибки. Список возможных значений приведен в таблице ниже.
* errorMessage Описание ошибки.
*
* В случае успешной регистрации:
* orderId Номер заказа в платежной системе. Уникален в пределах системы.
* formUrl URL платежной формы, на который надо перенаправить браузер клиента.
*
* Код ошибки Описание
* 0 Обработка запроса прошла без системных ошибок.
* 1 Заказ с таким номером уже зарегистрирован в системе.
* 3 Неизвестная (запрещенная) валюта.
* 4 Отсутствует обязательный параметр запроса.
* 5 Ошибка значения параметра запроса.
* 7 Системная ошибка.
*/
$response = gateway('register.do', $data);
/**
* ЗАПРОС РЕГИСТРАЦИИ ДВУХСТАДИЙНОГО ПЛАТЕЖА В ПЛАТЕЖНОМ ШЛЮЗЕ
* registerPreAuth.do
*
* Параметры и ответ точно такие же, как и в предыдущем методе.
* Необходимо вызывать либо register.do, либо registerPreAuth.do.
*/
// $response = gateway('registerPreAuth.do', $data);
if (isset($response['errorCode'])) { // В случае ошибки вывести ее
echo 'Ошибка #' . $response['errorCode'] . ': ' . $response['errorMessage'];
} else { // В случае успеха перенаправить пользователя на плетжную форму
header('Location: ' . $response['formUrl']);
die();
}
}
/**
* ОБРАБОТКА ДАННЫХ ПОСЛЕ ПЛАТЕЖНОЙ ФОРМЫ
*/
else if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['orderId'])){
$data = array(
'userName' => USERNAME,
'password' => PASSWORD,
'orderId' => $_GET['orderId']
);
/**
* ЗАПРОС СОСТОЯНИЯ ЗАКАЗА
* getOrderStatus
*
* ПАРАМЕТРЫ
* userName Логин магазина.
* password Пароль магазина.
* orderId Номер заказа в платежной системе. Уникален в пределах системы.
*
* ОТВЕТ
* ErrorCode Код ошибки. Список возможных значений приведен в таблице ниже.
* OrderStatus По значению этого параметра определяется состояние заказа в платежной системе.
* Список возможных значений приведен в таблице ниже. Отсутствует, если заказ не был найден.
*
* Код ошибки Описание
* 0 Обработка запроса прошла без системных ошибок.
* 2 Заказ отклонен по причине ошибки в реквизитах платежа.
* 5 Доступ запрещён;
* Пользователь должен сменить свой пароль;
* Номер заказа не указан.
* 6 Неизвестный номер заказа.
* 7 Системная ошибка.
*
* Статус заказа Описание
* 0 Заказ зарегистрирован, но не оплачен.
* 1 Предавторизованная сумма захолдирована (для двухстадийных платежей).
* 2 Проведена полная авторизация суммы заказа.
* 3 Авторизация отменена.
* 4 По транзакции была проведена операция возврата.
* 5 Инициирована авторизация через ACS банка-эмитента.
* 6 Авторизация отклонена.
*/
$response = gateway('getOrderStatus.do', $data);
// Вывод кода ошибки и статус заказа
echo '
<b>Error code:</b> ' . $response['ErrorCode'] . '<br />
<b>Order status:</b> ' . $response['OrderStatus'] . '<br />
';
}
?>
Также, для Сбера может понадобиться, чтобы на сайте были выполнены определенные условия, а именно:
- Чтобы на сайте была отображения информация о доставке и оплате;
- Необходимо, чтобы информация о доставке и оплате была на видном месте (например, в качестве пунктов в горизонтальном меню);
- Реквизиты организации в контактах или, также, в пункте меню. Можно сделать кнопку в контактах, по нажатию на которую появится всплываха с реквизитами:
- Организация
- ИНН
- ОГРН
- Юридический адрес