Skip to content

Commit 1b1b1c4

Browse files
committed
Merge branch 'YP-1357__podderzhka-tokenizatsii-sberpay' into 'main'
YP-1357__podderzhka-tokenizatsii-sberpay See merge request ypmn-public/php-api-client!12
2 parents afa25bd + eb7dccc commit 1b1b1c4

16 files changed

+596
-10
lines changed

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,39 +39,44 @@ docker compose up --detach
3939
##### 3. Подписки СБП
4040
1. [Создание подписки СБП](src/Examples/getBindingFasterPayment.php)
4141
2. [Оплата по подписке СБП](src/Examples/paymentByFasterBinding.php)
42+
43+
##### 4. Подписки SberPay
44+
1. [Создание подписки SberPay](src/Examples/getBindingPays.php)
45+
2. [Оплата по подписке SberPay](src/Examples/paymentByBindingPays.php)
4246

43-
##### 4. Токенизация карты (чтобы запомнить карту клиента и не вводить повторно)
47+
##### 5. Токенизация карты (чтобы запомнить карту клиента и не вводить повторно)
4448
1. [Создание платёжного токена ](src/Examples/getToken.php)
4549
2. [Оплата токеном](src/Examples/paymentByToken.php)
4650

47-
##### 5. Отчёты
51+
##### 6. Отчёты
4852
1. [Проверка статуса платежа](src/Examples/paymentGetStatus.php)
4953
2. [Запрос детального отчета по заказу](src/Examples/getReportOrderDetails.php)
5054
3. [Запрос быстрого отчёта по заказам для сверки](src/Examples/getReportOrder.php)
5155
4. [Запрос отчёта по заказам](src/Examples/getReportGeneral.php)
5256
5. [Запрос отчёта в виде графика](src/Examples/getReportChart.php)
5357

54-
##### 6. Возврат средств плательщику (Refund)
58+
##### 7. Возврат средств плательщику (Refund)
5559
1. [Возврат средств](src/Examples/paymentRefund.php)
5660
2. [Возврат средств со сплитом (разделением платежа)](src/Examples/paymentRefundMarketplace.php)
5761

58-
##### 7. Выплаты
62+
##### 8. Выплаты
5963
1. [Выплаты на банковские карты](src/Examples/payoutCreate.php)
64+
2. [Запрос баланса для выплаты](src/Examples/payoutGetBalance.php)
6065

61-
##### 8. [Безопасные поля (Secure fields)](src/Examples/secureFields.php)
66+
##### 9. [Безопасные поля (Secure fields)](src/Examples/secureFields.php)
6267
2. [Создание сессии](src/Examples/getSession.php)
6368
3. [Оплата одноразовым токеном](src/Examples/oneTimeTokenPayment.php)
6469

65-
##### 9. [Страница после оплаты](src/Examples/returnPage.php)
70+
##### 10. [Страница после оплаты](src/Examples/returnPage.php)
6671

67-
##### 10. Подключение продавцов (сабмерчантов маркетплейсов)
72+
##### 11. Подключение продавцов (сабмерчантов маркетплейсов)
6873
1. [Подключение продавца-юридического лица (отправка анкеты)](src/Examples/qstCreateOrg.php)
6974
2. [Подключение продавца-ИП (отправка анкеты)](src/Examples/qstCreateIp.php)
7075
3. [Получение статуса анкеты](src/Examples/qstStatus.php)
7176
4. [Печать анкеты](src/Examples/qstPrint.php)
7277
5. [Список анкет](src/Examples/qstList.php)
7378

74-
##### 11. Виджет
79+
##### 12. Виджет
7580
- [Подключение виджета](src/Examples/getWidget.php)
7681

7782
## Ссылки

example.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
case 'paymentCapture':
2727
case 'paymentGetStatus':
2828
case 'payoutCreate':
29+
case 'payoutGetBalance':
2930
case 'paymentWebhook':
3031
case 'paymentRefund':
3132
case 'paymentRefundMarketplace':
@@ -41,6 +42,8 @@
4142
case 'getFasterPaymentWithReceipts':
4243
case 'getBindingFasterPayment':
4344
case 'paymentByFasterBinding':
45+
case 'paymentByBindingPays':
46+
case 'getBindingPays':
4447
case 'qstCreateOrg':
4548
case 'qstCreateIp':
4649
case 'qstStatus':

example_list.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@
5252
'docLink' => 'https://ypmn.ru/ru/documentation/',
5353
'link' => '',
5454
],
55+
'getBindingPays' => [
56+
'name' => 'Создание токена SberPay',
57+
'about' => 'В этом примере отправляется запрос на создание токена SberPay с одновременной оплатой',
58+
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/payment-api/paths/~1v4~1payments~1authorize/post',
59+
'link' => '',
60+
],
61+
'paymentByBindingPays' => [
62+
'name' => 'Оплата по токену SberPay',
63+
'about' => 'Это пример демонстрирует оплату через SberPay по средством ранее созданного токена',
64+
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/payment-api/paths/~1v4~1payments~1authorize/post',
65+
'link' => '',
66+
],
5567
'getPaymentLinkMarketplace' => [
5668
'name' => 'Платёж со сплитом',
5769
'about' => 'Это пример платежа со сплитом (разделением оплаты на несколько плательщиков).',
@@ -106,6 +118,12 @@
106118
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/payouts-api',
107119
'link' => '',
108120
],
121+
'payoutGetBalance' => [
122+
'name' => 'Получение баланса для выплаты',
123+
'about' => 'Запрос к YPMN для проверки баланса на вылпату',
124+
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/payouts-api/paths/~1v4~1payout~1balance/get',
125+
'link' => '',
126+
],
109127
'getSession' => [
110128
'name' => 'Создание сессии',
111129
'about' => 'Создание уникальной сессии YPMN',

src/ApiRequest.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class ApiRequest implements ApiRequestInterface
1919
public const REFUND_API = '/api/v4/payments/refund';
2020
public const STATUS_API = '/api/v4/payments/status';
2121
public const PAYOUT_CREATE_API = '/api/v4/payout';
22+
public const PAYOUT_GET_BALANCE_API = '/api/v4/payout/balance';
2223
public const REPORTS_ORDERS_API = '/reports/orders';
2324
public const SESSION_API = '/api/v4/payments/sessions';
2425
public const REPORT_CHART_API = '/api/v4/reports/chart';
@@ -542,6 +543,31 @@ public function sendPayoutCreateRequest(PayoutInterface $payout): array
542543
return $this->sendPostRequest($payout, self::PAYOUT_CREATE_API);
543544
}
544545

546+
/**
547+
* @inheritdoc
548+
* @throws PaymentException
549+
*/
550+
public function sendPayoutGetBalanceRequest(array $params = []): array
551+
{
552+
$url = self::PAYOUT_GET_BALANCE_API;
553+
554+
if (!empty($params)) {
555+
$url .= '?' . http_build_query($params);
556+
}
557+
558+
$responseData = $this->sendGetRequest($url);
559+
560+
if (mb_strlen($responseData['error']) > 0) {
561+
throw new PaymentException($responseData['error']);
562+
}
563+
564+
if ($responseData['response'] == null || strlen($responseData['response']) === 0) {
565+
throw new PaymentException('Непредвиденная ошибка!.');
566+
}
567+
568+
return $responseData;
569+
}
570+
545571
/** @inheritdoc
546572
* @throws PaymentException
547573
*/
@@ -700,7 +726,7 @@ class="w-100 d-block"
700726
border: 1px solid green;
701727
white-space: pre-wrap;
702728
"
703-
>' . print_r($mixedInput, true) . '</pre>';
729+
>' . htmlspecialchars(print_r($mixedInput, true)) . '</pre>';
704730
}
705731
}
706732

src/ApiRequestInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ public function sendTokenCreationRequest(PaymentReference $payuPaymentReference)
104104
*/
105105
public function sendTokenPaymentRequest(MerchantToken $tokenHash): array;
106106

107+
/**
108+
* Отправить запрос на получение баланса
109+
* @param array $params
110+
* @return array
111+
*/
112+
public function sendPayoutGetBalanceRequest(array $params = []): array;
113+
107114
/**
108115
* Отправить запрос для получения графика
109116
* @param array $params

src/Examples/getBindingPays.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
/**
3+
* getBindingPays.php
4+
*/
5+
declare(strict_types=1);
6+
7+
use Ypmn\Product;
8+
use Ypmn\ApiRequest;
9+
use Ypmn\Billing;
10+
use Ypmn\Delivery;
11+
use Ypmn\IdentityDocument;
12+
use Ypmn\Client;
13+
use Ypmn\Payment;
14+
use Ypmn\Authorization;
15+
use Ypmn\PaymentException;
16+
use Ypmn\Std;
17+
use Ypmn\StoredCredentials;
18+
19+
// Подключим файл, в котором заданы параметры мерчанта
20+
include_once 'start.php';
21+
22+
/** @var \Ypmn\Merchant $merchant */
23+
24+
/*
25+
* Оплата через SberPay с запросом на создание токена
26+
*/
27+
28+
/* Опишем первую позицию */
29+
$product1 = new Product();
30+
$product1->setName('Круассаны Цезарь'); // Установим Наименование товара или услуги
31+
$product1->setSku('toy-01'); // Установим Артикул
32+
$product1->setVat(20); // Установим НДС
33+
$product1->setUnitPrice(10); // Установим Стоимость за единицу
34+
$product1->setQuantity(1); // Установим Количество
35+
36+
/* Опишем вторую позицию с помощью сокращённого синтаксиса */
37+
$product2 = new Product([
38+
'name' => 'Ассорти рулетиков Нежность',
39+
'sku' => 'toy-02',
40+
'unitPrice' => 8,
41+
'quantity' => 3,
42+
'vat' => 10,
43+
]);
44+
45+
/* Опишем третью позицию с помощью JSON */
46+
$product3 = new Product(
47+
json_decode(
48+
'{
49+
"name": "Ассорти мини-десертов",
50+
"sku": "toy-03",
51+
"unitPrice": 12,
52+
"quantity": 2,
53+
"vat": 0
54+
}',
55+
true
56+
)
57+
);
58+
59+
/* Опишем Биллинговую (платёжную) информацию */
60+
$billing = new Billing;
61+
$billing->setCountryCode('RU'); // Установим Код страны
62+
$billing->setCity('Москва'); // Установим Город
63+
$billing->setState('Центральный регион'); // Установим Регион
64+
$billing->setAddressLine1('Улица Старый Арбат, дом 10'); // Установим Адрес Плательщика (первая строка)
65+
$billing->setAddressLine2('Офис Ypmn'); // Установим Адрес Плательщика (вторая строка)
66+
$billing->setZipCode('121000'); // Установим Почтовый Индекс Плательщика
67+
$billing->setFirstName('Иван'); // Установим Имя Плательщика
68+
$billing->setLastName('Петров'); // Установим Фамилия Плательщика
69+
$billing->setPhone('9670660742'); // Установим Телефон Плательщика
70+
$billing->setEmail('[email protected]'); // Установим Email Плательщика
71+
72+
/* Опишем Доствку и принимающее лицо (необязательно) */
73+
$delivery = new Delivery;
74+
// Установим документ, подтверждающий право приёма доставки
75+
$delivery->setIdentityDocument(
76+
new IdentityDocument(123456, 'PERSONALID')
77+
);
78+
$delivery->setCountryCode('RU'); // Установим Код страны
79+
$delivery->setCity('Москва'); // Установим Город
80+
$delivery->setState('Центральный регион'); // Установим Регион
81+
$delivery->setAddressLine1('Улица Старый Арбат, дом 10'); // Установим Адрес Лица, принимающего заказ (первая строка)
82+
$delivery->setAddressLine2('Офис Ypmn'); // Установим Адрес Лица, принимающего заказ (вторая строка)
83+
$delivery->setZipCode('121000'); // Установим Почтовый Индекс Лица, принимающего заказ
84+
$delivery->setFirstName('Мария'); // Установим Имя Лица, принимающего заказ
85+
$delivery->setLastName('Петрова'); // Установим Фамилия Лица, принимающего заказ
86+
$delivery->setPhone('89670660743'); // Установим Телефон Лица, принимающего заказ
87+
$delivery->setEmail('[email protected]'); // Установим Email Лица, принимающего заказ
88+
$delivery->setCompanyName('ООО "Вектор"'); // Установим Название Компании, в которой можно оставить заказ
89+
90+
/* Создадим клиентское подключение */
91+
$client = new Client;
92+
$client->setBilling($billing); // Установим биллинг
93+
$client->setDelivery($delivery); // Установим доставку
94+
$client->setCurrentClientIp(); // Установим IP (автоматически)
95+
$client->setCurrentClientTime(); // И Установим время (автоматически)
96+
97+
/* Создадим платёж */
98+
$payment = new Payment;
99+
$payment->addProduct($product1); // Установим товарную позицию 1
100+
$payment->addProduct($product2); // Установим товарную позицию 2
101+
$payment->addProduct($product3); // Установим товарную позицию 3
102+
$payment->setCurrency('RUB'); // Установим валюту
103+
104+
/* Создадим авторизацию по типу платежа */
105+
$authorization = new Authorization('SBERPAY',false);
106+
107+
/* Запрашиваем подписку */
108+
$storedCredentials = new StoredCredentials();
109+
$storedCredentials->setConsentType("recurring");
110+
$storedCredentials->setSubscriptionPurpose("Ежедневная доставка \"К Завтраку\"");
111+
112+
// Назначим авторизацию для нашего платежа //
113+
$payment->setAuthorization($authorization);
114+
// Запросим подписку
115+
$payment->setStoredCredentials($storedCredentials);
116+
// Установим номер заказа (должен быть уникальным в вашей системе) //
117+
$payment->setMerchantPaymentReference('primer_nomer__' . time());
118+
// Установим адрес перенаправления пользователя после оплаты //
119+
$payment->setReturnUrl('http://' . $_SERVER['SERVER_NAME'] . '/php-api-client/?function=returnPage');
120+
$payment->setClient($client); // Установим клиентское подключение
121+
122+
/* Создадим HTTP-запрос к API */
123+
$apiRequest = new ApiRequest($merchant);
124+
125+
// Включить режим отладки (закомментируйте или удалите в рабочей программе!) //
126+
$apiRequest->setDebugMode();
127+
// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
128+
$apiRequest->setSandboxMode();
129+
130+
// Отправим запрос //
131+
$responseData = $apiRequest->sendAuthRequest($payment);
132+
133+
/* Преобразуем ответ из JSON в массив */
134+
try {
135+
$responseData = json_decode((string) $responseData["response"], true);
136+
137+
// Нарисуем кнопку оплаты
138+
echo Std::drawYpmnButton([
139+
'url' => $responseData["paymentResult"]['url'] ?? "",
140+
'sum' => $payment->sumProductsAmount() ?? 0,
141+
]);
142+
143+
// Либо сделаем редирект (перенаправление) браузера по адресу оплаты:
144+
// echo Std::redirect($responseData["paymentResult"]['url']);
145+
} catch (Exception $exception) {
146+
//TODO: обработка исключения
147+
echo Std::alert([
148+
'text' => '
149+
Извините, платёжный метод временно недоступен.<br>
150+
Вы можете попробовать другой способ оплаты, либо свяжитесь с продавцом.<br>
151+
<br>
152+
<pre>' . $exception->getMessage() . '</pre>',
153+
'type' => 'danger',
154+
]);
155+
156+
throw new PaymentException('Платёжный метод временно недоступен');
157+
}

0 commit comments

Comments
 (0)