Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ docker compose up --detach

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

##### 10. Подключение продавцов
1. [Подключение продавца-организации (отправка анкеты)](src/Examples/qstCreateOrg.php)
2. [Подключение продавца-ИП (отправка анкеты)](src/Examples/qstCreateIp.php)
3. [Получение статуса анкеты](src/Examples/qstStatus.php)
4. [Печать анкеты](src/Examples/qstPrint.php)
5. [Список анкет](src/Examples/qstList.php)

## Ссылки
- [НКО «Твои Платежи»](https://YPMN.ru/)
- [Докуметация API](https://ypmn.ru/ru/documentation/)
Expand Down
6 changes: 6 additions & 0 deletions example.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
case 'getFasterPayment':
case 'getBindingFasterPayment':
case 'paymentByFasterBinding':
case 'qstCreateOrg':
case 'qstCreateIp':
case 'qstStatus':
case 'qstPrint':
case 'SOMGetPaymentLink':
case 'qstList':
require './src/Examples/start.php';
@include './src/Examples/'.$_GET['function'] . '__prepend.php';
require './src/Examples/'.$_GET['function'] . '.php';
Expand Down
32 changes: 31 additions & 1 deletion example_list.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,39 @@
'link' => '',
],
'SOMGetPaymentLink' => [
'name' => 'Самая простая кнопка оплаты',
'name' => 'Оплата зарубежными картами',
'about' => 'В этом примере показана простая реализация оплаты заказа зарубежной картой.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/payment-api',
'link' => '',
],
'qstCreateOrg' => [
'name' => 'Подключение продавца-организации (отправка анкеты)',
'about' => 'В этом примере показана реализация отправки анкеты подключаемого продавца-организации на проверку в YPMN.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1create/post',
'link' => '',
],
'qstCreateIp' => [
'name' => 'Подключение продавца-ИП (отправка анкеты)',
'about' => 'В этом примере показана реализация отправки анкеты подключаемого продавца-ИП на проверку в YPMN.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1create/post',
'link' => '',
],
'qstStatus' => [
'name' => 'Получение статуса анкеты',
'about' => 'В этом примере показано получение статуса анкеты по её ID.<br/><br/>ID анкеты возвращается при отправке анкеты на проверку.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1status~1%7Bid%7D/get',
'link' => '',
],
'qstPrint' => [
'name' => 'Печать анкеты',
'about' => 'В этом примере показано получение заполненной pdf версии анкеты по её ID.<br/><br/>ID анкеты возвращается при отправке анкеты на проверку.<br/><br/>Распечатать можно только одобренную анкету - в статусе approved.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1print~1%7Bid%7D/get',
'link' => '',
],
'qstList' => [
'name' => 'Список анкет',
'about' => 'В этом примере показано получение списка анкет.',
'docLink' => 'https://ypmn.ru/ru/documentation/#tag/qst-api/paths/~1v4~1qst~1list/get',
'link' => '',
],
];
95 changes: 91 additions & 4 deletions src/ApiRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class ApiRequest implements ApiRequestInterface
const REPORT_ORDERS_API_V4 = '/api/v4/reports/orders';
const REPORT_ORDER_DETAILS_API = '/api/v4/reports/order-details';
const PODELI_MERCHANT_REGISTRATION_API = '/api/v4/registration/merchant/podeli';
const QST_CREATE_API = '/api/v4/qst/create';
const QST_STATUS_API = '/api/v4/qst/status';
const QST_PRINT_API = '/api/v4/qst/print';
const QST_LIST_API = '/api/v4/qst/list';
const HOST = 'https://secure.ypmn.ru';
const SANDBOX_HOST = 'https://sandbox.ypmn.ru';
const LOCAL_HOST = 'http://127.0.0.1';
Expand All @@ -40,6 +44,9 @@ class ApiRequest implements ApiRequestInterface
/** @var bool Режим Отладки (вывод системных сообщений) */
private bool $debugModeIsOn = false;

/** @var bool Отображать заголовки ответа в режим отладки */
private bool $debugShowResponseHeaders = true;

/** @var bool Формат результата в режиме отладки */
private bool $jsonDebugResponse = true;

Expand Down Expand Up @@ -220,6 +227,12 @@ private function sendGetRequest(string $api): array
]
];

$headers = [];

if ($this->getDebugShowResponseHeaders()) {
$this->addCurlOptHeaderFunction($setopt_array, $headers);
}

curl_setopt_array($curl, $setopt_array);

$response = curl_exec($curl);
Expand All @@ -231,11 +244,16 @@ private function sendGetRequest(string $api): array
$this->echoDebugMessage($this->getHost() . $api);
$this->echoDebugMessage('Ответ от сервера Ypmn:');
if ($this->getJsonDebugResponse()) {
$this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT));
$this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
} else {
$this->echoDebugMessage($response);
}

if ($this->getDebugShowResponseHeaders()) {
$this->echoDebugMessage('Заголовки ответа от сервера Ypmn:');
$this->echoDebugMessage(implode("\n", $headers));
}

if (mb_strlen($err) > 0) {
$this->echoDebugMessage('Ошибка');
echo '<br>Вы можете отправить запрос на поддержку на <a href="mailto:itsupport@ypmn.ru?subject=YPMN_Integration">itsupport@ypmn.ru</a>';
Expand Down Expand Up @@ -296,7 +314,7 @@ public function sendPostRequest($data, string $api): array
$date = (new DateTime())->format(DateTimeInterface::ATOM);
$requestHttpVerb = 'POST';

curl_setopt_array($curl, [
$setOptArray = [
CURLOPT_URL => $this->getHost() . $api,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
Expand All @@ -318,7 +336,15 @@ public function sendPostRequest($data, string $api): array
$encodedJsonDataHash
)
]
]);
];

$headers = [];

if ($this->getDebugShowResponseHeaders()) {
$this->addCurlOptHeaderFunction($setOptArray, $headers);
}

curl_setopt_array($curl, $setOptArray);

$response = curl_exec($curl);
$err = curl_error($curl);
Expand All @@ -328,7 +354,12 @@ public function sendPostRequest($data, string $api): array
$this->echoDebugMessage('POST-Запрос к серверу Ypmn:');
$this->echoDebugMessage($encodedJsonData);
$this->echoDebugMessage('Ответ от сервера Ypmn:');
$this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT));
$this->echoDebugMessage(json_encode(json_decode($response), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));

if ($this->getDebugShowResponseHeaders()) {
$this->echoDebugMessage('Заголовки ответа от сервера Ypmn:');
$this->echoDebugMessage(implode("\n", $headers));
}

if (mb_strlen($err) > 0) {
$this->echoDebugMessage('Ошибка');
Expand Down Expand Up @@ -594,4 +625,60 @@ public function sendPodeliRegistrationMerchantRequest(PodeliMerchant $merchant):
{
return $this->sendPostRequest($merchant, self::PODELI_MERCHANT_REGISTRATION_API);
}

/** @inheritdoc */
public function sendQstCreateRequest(QstInterface $qst): array
{
return $this->sendPostRequest($qst, self::QST_CREATE_API);
}

/** @inheritdoc */
public function sendQstStatusRequest(int $qstId): array
{
return $this->sendGetRequest(self::QST_STATUS_API . '/' . $qstId);
}

/** @inheritdoc */
public function sendQstPrintRequest(int $qstId): array
{
return $this->sendGetRequest(self::QST_PRINT_API . '/' . $qstId);
}

/** @inheritdoc */
public function sendQstListRequest(): array
{
return $this->sendGetRequest(self::QST_LIST_API);
}

/** @inheritdoc */
public function getDebugShowResponseHeaders(): bool
{
return $this->debugShowResponseHeaders;
}

/** @inheritdoc */
public function setDebugShowResponseHeaders(bool $debugShowResponseHeaders = true): self
{
$this->debugShowResponseHeaders = $debugShowResponseHeaders;
return $this;
}

/**
* @param array $curlOptArr
* @param array $headers
* @return void
*/
private function addCurlOptHeaderFunction(array &$curlOptArr, array &$headers): void
{
$curlOptArr += [
CURLOPT_HEADERFUNCTION => static function($curl, $header) use (&$headers)
{
if (strlen(trim($header)) > 0) {
$headers[] = trim($header);
}

return strlen($header);
}
];
}
}
40 changes: 40 additions & 0 deletions src/ApiRequestInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,44 @@ public function setHost(string $host) : self;
* @return array
*/
public function sendPodeliRegistrationMerchantRequest(PodeliMerchant $merchant): array;

/**
* Отправить запрос на создание и отправку анкеты (по добавлению продавцов) на проверку
* @param Qst $qst
* @return array
*/
public function sendQstCreateRequest(QstInterface $qst): array;

/**
* Получить статус анкеты
* @param int $qstId
* @return array
*/
public function sendQstStatusRequest(int $qstId): array;

/**
* Распечатать анкету
* @param int $qstId
* @return array
*/
public function sendQstPrintRequest(int $qstId): array;

/**
* Получить список анкет
* @return array
*/
public function sendQstListRequest(): array;

/**
* Получить установлен ли режим показывать заголовки ответа в режиме отладки
* @return bool
*/
public function getDebugShowResponseHeaders(): bool;

/**
* Установить показывать заголовки ответа в режиме отладки
* @param bool $debugShowResponseHeaders
* @return self
*/
public function setDebugShowResponseHeaders(bool $debugShowResponseHeaders = true): self;
}
2 changes: 1 addition & 1 deletion src/Examples/getToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<br>
<br>Вот он: <code>' . $responseData['token'] . '</code>
<br>
<br>Тперь его <a href="./?function=paymentByToken&token=' . $responseData['token'] . '">можно использовать</a> в платежах вместо данных карты
<br>Теперь его <a href="./?function=paymentByToken&token=' . $responseData['token'] . '">можно использовать</a> в платежах вместо данных карты
',
]);
}
Expand Down
89 changes: 89 additions & 0 deletions src/Examples/qstCreateIp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

declare(strict_types=1);

use Ypmn\ApiRequest;
use Ypmn\Qst;
use Ypmn\QstSchema;
use Ypmn\QstSchemaActualAddress;
use Ypmn\QstSchemaBankAccount;
use Ypmn\QstSchemaIdentityDoc;
use Ypmn\QstSchemaLegalAddress;
use Ypmn\QstSchemaPostAddress;

// Подключим файл, в котором заданы параметры мерчанта
include_once 'start.php';

/* Создание и отправка анкеты для подключения продавца */

/* Создаем и заполняем объект анкеты */
$qst = new Qst();

/* ИНН продавца */
$qst->setInn('773200328662');

/* Данные продавца */
$qstSchema = new QstSchema();
$qstSchema->addPhone('+7 495 1234567, доб. 123');
$qstSchema->addEmail('example@ypmn.com');

$qstLegalAddress = (new QstSchemaLegalAddress())
->setZip('123456')
->setRegion('Москва')
->setCity('Москва')
->setStreet('ул. Охотный ряд')
->setHouse('1');
$qstSchema->setLegalAddress($qstLegalAddress);

$qstActualAddress = (new QstSchemaActualAddress())->setChecked(true);
$qstSchema->setActualAddress($qstActualAddress);

$qstPostAddress = (new QstSchemaPostAddress())->setChecked(true);
$qstSchema->setPostAddress($qstPostAddress);

$qstIdentityDoc = (new QstSchemaIdentityDoc())
->setSeries('1234')
->setNumber('123456')
->setIssueDate('2000-01-30')
->setIssuedBy('МВД')
->setIssuedByKP('123-456');

$qstSchema
->setBirthDate('1969-02-23')
->setBirthPlace('Москва')
->setIdentityDoc($qstIdentityDoc);

$qstBankAccount = (new QstSchemaBankAccount())
->setBankBIK('044525700')
->setBankCorAccount('30101810200000000700')
->setBankAccount('40702810100002400756');

$qstSchema->addBankAccount($qstBankAccount);

$qstSchema->setAdditionalFieldByKey(1, 'Доп. поле');

$qst->setSchema($qstSchema);

/* Создадим HTTP-запрос к API */
$apiRequest = new ApiRequest($merchant);

// Включить режим отладки (закомментируйте или удалите в рабочей программе!) //
$apiRequest->setDebugMode();
// Переключиться на тестовый сервер (закомментируйте или удалите в рабочей программе!) //
$apiRequest->setSandboxMode();

/* Запрос на отправку анкеты */
$responseData = $apiRequest->sendQstCreateRequest($qst);

/* Преобразуем ответ из JSON в массив */
try {
$responseData = json_decode((string) $responseData["response"], true);
if (isset($responseData['id'])) {
echo "Анкета #{$responseData['id']} создана и отправлена на проверку";
} else {
echo "Анкета не создана, см. причину в ответа от сервера YPMN";
}
} catch (Exception $exception) {
echo "Ошибка запроса: {$exception->getMessage()}";
throw new Exception($exception->getMessage());
}
Loading