После регистрации в системе эквайринга Сбербанка и получив доступ к тестовой среде, можно приступить к интеграции с интернет-магазином. Рассмотрим примеры основных обращений к REST API Сбербанка с помощью PHP CURL.
В примерах указаны URL для тестовой среды, после перехода в боевой режим, их нужно заменить на https://securepayments.sberbank.ru/
При данном методе деньги клиента списываются сразу. Клиент добавляет товары в корзину, оформляет заказ, на этапе оплаты нужно сделать запрос в платежный шлюз на register.do
.
Описание одностадийной оплаты, подробнее о передаче корзины.
$vars = array();
$vars['userName'] = 'логин';
$vars['password'] = 'пароль';
/* ID заказа в магазине */
$vars['orderNumber'] = '123';
/* Корзина для чека (необязательно) */
$cart = array(
array(
'positionId' => 1,
'name' => 'Название товара',
'quantity' => array(
'value' => 1,
'measure' => 'шт'
),
'itemAmount' => 1 * (1000 * 100),
'itemCode' => '123456',
'tax' => array(
'taxType' => 0,
'taxSum' => 0
),
'itemPrice' => 1000 * 100,
)
);
$vars['orderBundle'] = json_encode(
array(
'cartItems' => array(
'items' => $cart
)
),
JSON_UNESCAPED_UNICODE
);
/* Сумма заказа в копейках */
$vars['amount'] = 1000 * 100;
/* URL куда клиент вернется в случае успешной оплаты */
$vars['returnUrl'] = 'http://example.com/success/';
/* URL куда клиент вернется в случае ошибки */
$vars['failUrl'] = 'http://example.com/error/';
/* Описание заказа, не более 24 символов, запрещены % + \r \n */
$vars['description'] = 'Заказ №' . $order_id . ' на example.com';
$ch = curl_init('https://3dsec.sberbank.ru/payment/rest/register.do?' . http_build_query($vars));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
Ответ будет в формате JSON, в котором содержатся ID платежа в банке и URL куда отправить клиента для оплаты.
{
"errorCode":"0",
"orderId":"70906e55-7114-41d6-8332-4609dc6590f4",
"formUrl":"https://3dsec.sberbank.ru/payment/merchants/test/payment_ru.html?mdOrder=70906e55-7114-41d6-8332-4609dc6590f4"
}
Далее обработаем ответ, и перенаправим клиента:
$res = json_decode($res, JSON_OBJECT_AS_ARRAY);
if (empty($res['orderId'])){
/* Возникла ошибка: */
echo $res['errorMessage'];
} else {
/* Успех: */
/* Тут нужно сохранить ID платежа в своей БД - $res['orderId'] */
/* Перенаправление клиента на страницу оплаты */
header('Location: ' . $res['formUrl'], true);
/* Или на JS */
echo '<script>document.location.href = "' . $res['formUrl'] . '"</script>';
}
В случае успешной оплаты, клиент вернется на страницу returnUrl
. В адрес добавятся ID платежа полученный ранее:
http://example.com/success/?orderId=70906e55-7114-41d6-8332-4609dc6590f4&lang=ru
Также будет и в случаи ошибки (failUrl
):
http://example.com/error/?orderId=70906e55-7114-41d6-8332-4609dc6590f4&lang=ru
В этом методе деньги клиента холдируются (замораживаются), после этого магазин должен подтвердить платеж или его отменить. Описание на https://developer.sberbank.ru/doc/v1/acquiring/rest-requests2pay
Регистрация платежа отличается только методом registerPreAuth.do
.
$vars = array();
$vars['userName'] = 'логин';
$vars['password'] = 'пароль';
/* ID заказа в магазине */
$vars['orderNumber'] = '123';
/* Корзина для чека (необязательно) */
$cart = array(
array(
'positionId' => 1,
'name' => 'Название товара',
'quantity' => array(
'value' => 1,
'measure' => 'шт'
),
'itemAmount' => 1 * (1000 * 100),
'itemCode' => '123456',
'tax' => array(
'taxType' => 0,
'taxSum' => 0
),
'itemPrice' => 1000 * 100,
)
);
$vars['orderBundle'] = json_encode(
array(
'cartItems' => array(
'items' => $cart
)
),
JSON_UNESCAPED_UNICODE
);
/* Сумма заказа в копейках */
$vars['amount'] = 1000 * 100;
/* URL куда клиент вернется в случае успешной оплаты */
$vars['returnUrl'] = 'http://example.com/success/';
/* URL куда клиент вернется в случае ошибки */
$vars['failUrl'] = 'http://example.com/error/';
/* Описание заказа, не более 24 символов, запрещены % + \r \n */
$vars['description'] = 'Заказ №' . $order_id . ' на example.com';
$ch = curl_init('https://3dsec.sberbank.ru/payment/rest/registerPreAuth.do?' . http_build_query($vars));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
Если запрос возвращает ошибку, то возможно в вашем аккаунте отключены двухстадийные платежи, включить их можно через службу поддержки.
После оплаты, платеж подтверждается методом deposit.do
.
В этом методе сумма платежа может быть меньше исходной, в таком случаи остаток вернется клиенту.
$vars = array();
$vars['userName'] = 'логин';
$vars['password'] = 'пароль';
/* Номер заказа в платежной системе */
$vars['orderId'] = '70906e55-7114-41d6-8332-4609dc6590f4';
/* Сумма платежа в копейках, Если указать 0, то завершение произойдет на всю сумму. */
$vars['amount'] = 1000 * 100;
/* Если в первом запросе была передана корзина, то её нужно продублировать */
$cart = array(
array(
'positionId' => 1,
'name' => 'Название товара',
'quantity' => array(
'value' => 1,
'measure' => 'шт'
),
'itemAmount' => 1000 * 100,
'itemCode' => '123456',
'tax' => array(
'taxType' => 0,
'taxSum' => 0
),
'itemPrice' => 1000 * 100,
)
);
$vars['depositItems'] = json_encode(
array(
'items' => $cart
),
JSON_UNESCAPED_UNICODE
);
$ch = curl_init('https://3dsec.sberbank.ru/payment/rest/deposit.do?' . http_build_query($vars));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
$res = json_decode($res, JSON_OBJECT_AS_ARRAY);
if (!empty($res['errorCode'])) {
echo $res['errorMessage'];
} else {
echo 'Оплата завершена';
}
Методы getOrderStatus.do
и getOrderStatusExtended.do
возвращают данные о платеже.
$vars = array();
$vars['userName'] = 'логин';
$vars['password'] = 'пароль';
$vars['orderId'] = '70906e55-7114-41d6-8332-4609dc6590f4';
$ch = curl_init('https://3dsec.sberbank.ru/payment/rest/getOrderStatusExtended.do?' . http_build_query($vars));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
$res = json_decode($res, JSON_OBJECT_AS_ARRAY);
print_r($res);
Результат
Array
(
[errorCode] => 0
[errorMessage] => Успешно
[orderNumber] => 123
[orderStatus] => 1
[actionCode] => 0
[actionCodeDescription] =>
[amount] => 1000
[currency] => 643
[date] => 1540207733683
[orderDescription] => Заказ №123 на example.com
[ip] => 192.168.27.138
[merchantOrderParams] => Array()
[attributes] => Array(
[0] => Array(
[name] => mdOrder
[value] => 70906e55-7114-41d6-8332-4609dc6590f4
)
)
[cardAuthInfo] => Array(
[expiration] => 201912
[cardholderName] => CARDHOLDER NAME
[approvalCode] => 123456
[pan] => 411111XXXXXX1111
)
[authDateTime] => 1540207881419
[terminalId] => 123456
[authRefNum] => 111111111111
[paymentAmountInfo] => Array(
[paymentState] => APPROVED
[approvedAmount] => 1000
[depositedAmount] => 0
[refundedAmount] => 0
)
[bankInfo] => Array(
[bankName] => TEST CARD
[bankCountryCode] => RU
[bankCountryName] => Россия
)
)
Выведем информацию на странице:
<?php
$orderStatus = array(
0 => 'Заказ зарегистрирован, но не оплачен',
1 => 'Предавторизованная сумма захолдирована (для двухстадийных платежей)',
2 => 'Проведена полная авторизация суммы заказа',
3 => 'Авторизация отменена',
4 => 'По транзакции была проведена операция возврата',
5 => 'Инициирована авторизация через ACS банка-эмитента',
6 => 'Авторизация отклонена',
);
?>
Статус:
<?php echo $orderStatus[$res['orderStatus']]; ?>
Сумма регистрации:
<?php echo $res['paymentAmountInfo']['approvedAmount'] / 100; ?> р.
Сумма списания:
<?php echo $res['paymentAmountInfo']['depositedAmount'] / 100; ?> р.
Сумма возврата:
<?php echo $res['paymentAmountInfo']['refundedAmount'] / 100; ?> р.
Дата:
<?php echo date('d.m.Y H:i:s', $res['date'] / 1000); ?>
Карта:
<?php echo $res['cardAuthInfo']['pan']; ?>,
<?php echo $res['cardAuthInfo']['expiration']; ?>,
<?php echo $res['cardAuthInfo']['cardholderName']; ?>
Банк:
<?php echo $res['bankInfo']['bankName']; ?>,
<?php echo $res['bankInfo']['bankCountryName']; ?>
Для запроса отмены оплаты заказа используется reverse.do
. Функция отмены доступна в течение ограниченного времени после оплаты, точные сроки необходимо уточнять в Банке.
$vars = array();
$vars['userName'] = 'логин';
$vars['password'] = 'пароль';
$vars['orderId'] = '70906e55-7114-41d6-8332-4609dc6590f4';
$ch = curl_init('https://3dsec.sberbank.ru/payment/rest/reverse.do?' . http_build_query($vars));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
$res = json_decode($res, JSON_OBJECT_AS_ARRAY);
if (!empty($res['errorCode'])) {
echo $res['errorMessage'];
} else {
echo 'Оплата отменена';
}
Вызвав метод refund.do
, средства будут возвращены плательщику. Система позволяет возвращать средства более одного раза, но в общей сложности не более первоначальной суммы списания.
// Сумма возврата.
$sum = 500;
$vars = array();
$vars['userName'] = 'логин';
$vars['password'] = 'пароль';
$vars['orderId'] = '70906e55-7114-41d6-8332-4609dc6590f4';
$vars['amount'] = $sum * 100;
$ch = curl_init('https://3dsec.sberbank.ru/payment/rest/refund.do?' . http_build_query($vars));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$res = curl_exec($ch);
curl_close($ch);
$res = json_decode($res, JSON_OBJECT_AS_ARRAY);
if (!empty($res['errorCode'])) {
echo $res['errorMessage'];
} else {
echo $sum . 'р. возвращены плательщику';
}
<?php
// Важно:
// 1) ЮKassa поддерживает не все параметры из документации Сбера. Если какой-то параметр не поддерживается, то он будет проигнорирован в запросе.
// 2) Параметр customerDetails обязателен в запросе (email или телефон плательщика, на которые онлайн-касса отправит чек)
// 3) В параметре measure нужно передавать только числовые значения.
// 4) Параметр НДС (tax) обязателен в запросе.
// 5) Стоимость товаров в параметре itemPrice нужно передавать в копейках. Сумма платежа (amount) должна быть эквивалентна сумме всех товаров в чеке/корзине (orderBundle).
// 6) Опциональный параметр taxSystem (система налогообложения) нужно передавать в общем списке параметров, не помещая его в orderBundle. Пример: userName=*&password=*&orderNumber=123&amount=100&returnUrl=https://site.ru/thank_you_page&failUrl=https://site.ru/fail&taxSystem=2&orderBundle={...}
// 7) Передача кода маркировки в чек возможна только если ваша онлайн-касса работает по ФФД 1.05.
// Массив для отправки запроса Sber API
$args = array(
'userName' => '123456',
'password' => 'live_',
'amount' => 100,
'returnUrl' => 'https://yandex.ru',
'failUrl' => 'https://yandex.ru',
'description' => 'Оплата Товара 1'
);
$args['orderNumber'] = rand(0,1000000000000);
// Корзина для чека
$cart = array(
array(
'name' => 'Товар 1',
'quantity' => array(
'value' => 1,
'measure' => '0'
),
'tax' => array(
'taxType' => 0
),
'itemPrice' => 1 * 100
)
);
// Объект orderBundle
$args['orderBundle'] = json_encode(
array(
'customerDetails' => array(
'email' => 'mail@yandex.ru'
),
'cartItems' => array(
'items' => $cart
)
),
JSON_UNESCAPED_UNICODE
);
// Отправка запроса
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://3dsec-payments.yookassa.ru/payment/rest/register.do');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($args, '', '&'));
$answ=curl_exec($ch);
curl_close($ch);
print_r($answ);
?>