Отправка файлов на подпись с Adobe Sign API

от автора

В документации Adobe сочетается большой объем информации и плохая организация этой информации. Поэтому когда перед мной стала задача отправлять документы через Adobe Sign Api, я потратил несколько дней чтобы понять как всё это работает. 

И вот моё решение перед вами. Надеюсь, оно сэкономит время и нервы тех кому только предстоит разобраться в этом. 

Порядок действий:

  1. Создаем статичный ключ для работы с API — Access token

  2. Получаем домены для работы с API — Base uris

  3. Загружаем документ

  4. Отправляем документ на подпись

  5. Проверяем статус подписи

  6. Сохраняем подписанный файл

Создаем статичный ключ для работы с API — Access token

Заходим в свой аккаунт на сайте Adobe Sign API: https://secure.echosign.com/public/login. Переходим на страницу Account. Выбираем Personal Preferences и Access Tokens.

Нажимаем на плюсик справа, вводим название, выбираем доступы и сохраняем.

Какие доступы нам нужны?

На этот вопрос у меня ответа нет, поэтому я выбрал все доступы, чтобы наверняка заработало. Да, это не безопасно, но зато так точно будет работать. Мне было важно, чтобы оно заработало.

После сохранения, кликаем на наш токен и нажимаем сверху “Integration Key”, чтобы получить наш токен.

Далее в перменной $accessToken будет именно этот токен.

Получаем домены для работы с API — Base uris

<?php // Access token, полученный выше $accessToken = '';  // Laravel фасад: // GET запрос // Доп. заголовок: Bearer $accessToken // URL: https://api.adobesign.com/api/rest/v6/baseUris $response = Http::withToken($accessToken)   ->get('https://api.adobesign.com/api/rest/v6/baseUris');  // В ответе JSON с полем apiAccessPoint  $apiAccessPoint = $response->json('apiAccessPoint');

В $apiAccessPoint домен для API запросов.

Загружаем документ

<?php // Access token, полученный выше $accessToken = '';  // Домен для API запросов, полученный выше $apiAccessPoint = '';  // Путь к pdf шаблону $template = file_get_contents($pathToTemplate);  // Laravel фасад: // POST multipart/form-data запрос // Доп. заголовок: Bearer $accessToken // URL: $apiAccessPoint.'/api/rest/v6/transientDocuments' // В теле указываем название файла, mime тип и содержимое файла $response = Http    ::withToken($accessToken)    ->baseUrl($apiAccessPoint)    ->asMultipart()    ->post('/api/rest/v6/transientDocuments', [        'File-Name' => 'document.pdf',        'Mime-Type' => 'application/pdf',        'File'      => $template    ]);  // В ответе JSON с полем transientDocumentId, что является ID загруженного дока $transientDocumentID = $response->json('transientDocumentId'); if ( ! $transientDocumentID) {    // Если не пришел ID документа, то обрабатываем ошибку } 

В переменной $transientDocumentID будет ID загруженного документа.

Отправляем документ на подпись

Далее мне надо было понять как отправить документ на подпись.

Сначала я пытался добавить в документ виджеты. Виджет — это поле ввода в которое пользователь может внести свои данные, включая подпись. Но виджетам необходимо указывать координаты, которые непонятно как связаны с реальным документом. 

Поэтому после нескольких часов поиска в интернете, я нашел руководство по тегам, которые можно добавить в шаблон, чтобы поля появились сами собой. 

Например, чтобы появилось поле подписи, нужно ввести тег {{ es:signer:signature }}

В документе это может выглядеть так:

Документ #1234

Исполнитель: Дмитрий Дмитриевич {{es:signer:signature }}

Далее необходимо сформировать тело запроса. Оно содержит некоторое количество полей:

<?php // Функция для формирования тела запроса. Используется ниже function getBodyForSignDocument($documentID, $email): array {    return [        // ID документа, полученный выше        "fileInfos"           => [            [                "transientDocumentId" => $documentID            ]        ],        // Название документа, которое увидит клиент        "name"                => "Series Document",        "participantSetsInfo" => [            [                "order"       => 1,                "role"        => "SIGNER",                "memberInfos" => [                    [                        // Почта клиента                        "email" => $email,                        "id"    => 1                    ]                ]            ]        ],        "signatureType"       => "ESIGN",        "state"               => "IN_PROCESS"    ]; } 

Теперь необходимо выполнить запрос на отправку файла на подпись:

<?php // Access token, полученный выше $accessToken = '';  // Домен для API запросов, полученный выше $apiAccessPoint = '';  // Тело запроса, функция которого писана выше $bodyForSignDocument = getBodyForSignDocument($transientDocumentID, $email);   // Laravel фасад: // POST application/json запрос // Доп. заголовок: Bearer $accessToken // URL: $apiAccessPoint.'/api/rest/v6/agreements' // Тело запроса описано выше $response = Http::withToken(self::API_TOKEN)                 ->baseUrl($apiAccessPoint)                 ->asJson()                 ->post(                     '/api/rest/v6/agreements',                     $bodyForSignDocument                 );  // В ответе JSON с ID загруженного документа. Он понадобится ниже $documentID = $response->json('id'); if ($response->status() != '201' || ! $documentID) {    // Если ID не пришел или документ не был первично обработан Adobe, обрабатываем ошибку } 

В переменной $documentID содержится ID документа, который был отправлен на подпись.

Проверяем статус подписи

<?php // Access token, полученный выше $accessToken = '';  // Домен для API запросов, полученный выше $apiAccessPoint = '';  // ID документа, полученный выше $documentID  // Laravel фасад: // GET запрос // Доп. заголовок: Bearer $accessToken // URL: $apiAccessPoint.'/api/rest/v6/agreements/'.$documentID $response = Http::withToken(self::API_TOKEN)                ->baseUrl($apiAccessPoint)                ->get('/api/rest/v6/agreements/' . $documentID);  // В ответе JSON с полем status $status = $response->json('status'); if ($status !== 'SIGNED') {    // Если статус не SIGNED, то ждем пока подпишут }

Сохраняем подписанный файл

<?php // Access token, полученный выше $accessToken = '';  // Домен для API запросов, полученный выше $apiAccessPoint = '';  // ID документа, полученный выше $documentID  // Полный путь до файла   $fileURLPath = $apiAccessPoint . 'api/rest/v6/agreements/' . $documentID . '/combinedDocument';  // Laravel фасад: // GET запрос // Доп. заголовок: Bearer $accessToken // URL: $apiAccessPoint.$fileURLPath $fileContent = Http::withToken(self::API_TOKEN)                   ->baseUrl($apiAccessPoint)                   ->get($fileURLPath);  // В теле ответа будет подписанный PDF файл, если раннее в статусе было SIGNED  $fileContent = $fileContent->body();

Источники. Примечания

Источники

Касательно авторизации

Изначально Adobe просит использовать авторизацию через кнопку «Войти через Adobe». Но такой способ мне не подходил, ибо система должна функционировать автономно без вмешательства пользователей. Авторизация — тоже вмешательство.

Именно поэтому была найдена альтернатива в виде статичного токена — access token.

Касательно параметров в POST методе /api/rest/v6/agreements

Советую ознакомиться с описанием запросов к API 6й версии для понимание что можно добавить и изменить.

Например, можно не отправлять сразу документ, а подготовить его, добавив те виджеты. И только потом отправлять. Либо же, можно добавить какие-то данные в документ через автозамену тегов в формат {{var.name}}

Прошлая статья на тему Adobe

«Генерация файлов с Adobe» — в статье описаны методы формирования файлов из doсx шаблонов.


ссылка на оригинал статьи https://habr.com/ru/post/709296/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *