Pular para o conteúdo principal

Processamento em background - Sessões de assinatura

Por padrão, o Rest PKI Core fará com que o usuário aguarde que os documentos sejam processados antes de enviá-lo de volta à sua aplicação. Se você quiser oferecer uma experiência mais ágil para seus usuários, habilite o processamento em background especificando EnableBackgroundProcessing = true na criação da sessão.

Em .NET:

var response = await restPkiService.CreateSignatureSessionAsync(new CreateSignatureSessionRequest() {
...
EnableBackgroundProcessing = true,
});
return Redirect(response.RedirectUrl);

Em PHP:

$request = new CreateSignatureSessionRequest();
$request->enableBackgroundProcessing = true;

$response = $service->createSignatureSession($request);

header("Location: {$response->redirectUrl}");

Em Java:

CreateSignatureSessionRequest request = new CreateSignatureSessionRequest();
request.setEnableBackgroundProcessing(true);

CreateSignatureSessionResponse response = restPkiService.createSignatureSession(request);

return "redirect:" + response.getRedirectUrl();

Integração direta por API:

POST {endpoint}/api/signature-sessions
{
...
"enableBackgroundProcessing": true
}

Nesse caso, o usuário será redirecionado de volta à sua aplicação assim que concluir as assinaturas, sem aguardar o processamento, Entretanto, o seu tratemento de retorno precisa ser adequado para lidar com o caso de uma sessão de assinatura cujos documentos ainda não estão prontos para download.

observação

Nenhuma adequação é necessária no caso do Fluxo com webhook, pois nesse caso não há tratamento de retorno

Estados adicionais​

Além dos estados Completed e UserCancelled, a sessão pode estar em dois outros estados quando o usuário chega de volta à sua aplicação: Processing e ProcessingError.

Enquanto uma sessão estiver em Processing, alguns documentos estarão com estado Processing e não estarão disponíveis para download. Apenas quando a sessão mudar de estado para Completed é que todos os documentos estarão prontos para download.

observação

O estado ProcessingError é uma condição rara que ocorre apenas caso o certificado do usuário seja revogado na janela de tempo entre o início da sessão e a conclusão do processamento. É perfeitamente apropriado que a sua aplicação ignore essa condição ou apenas lance uma exceção caso isso ocorra.

Adaptando o tratamento de retorno​

Vamos adaptar nosso tratamento de retorno para lidar com essas mudanças.

Em .NET:

public class SessionCallbackController : Controller {
...
public async Task<IActionResult> Index(Guid signatureSessionId) {
var session = await restPkiService.GetSignatureSessionAsync(signatureSessionId);
if (session.Status != SignatureSessionStatus.Completed && session.Status != SignatureSessionStatus.Processing) {
return Redirect("/");
}
return View(session);
}
}

Em PHP:

$sessionId = $_GET['signatureSessionId'];

$session = $service->getSignatureSession($sessionId);
if ($session->status != SignatureSessionStatus::COMPLETED && $session->status != SignatureSessionStatus::PROCESSING) {
header("Location: http://localhost:8000/");
exit;
}

Em Java:

@Controller
public class SessionCallbackController {
...
public String index(
Model model,
@RequestParam(value="signatureSessionId") String sessionId
) throws Exception {
SignatureSession session = restPkiService.getSignatureSession(UUID.fromString(sessionId));
if (session.getStatus() != SignatureSessionStatus.COMPLETED &&
session.getStatus() != SignatureSessionStatus.PROCESSING) {
return "redirect:/";
}
// O link de cada arquivo assinado vem do DocumentModel do documento, depois que ele é concluído
Map<UUID, String> signedFileUrls = new HashMap<>();
for (SignatureSessionDocument document : session.getDocuments()) {
if (document.getStatus() == DocumentStatus.COMPLETED) {
signedFileUrls.put(document.getId(), restPkiService.getDocumentModel(document.getId()).getSignedFile().getUrl());
}
}
model.addAttribute("session", session);
model.addAttribute("signedFileUrls", signedFileUrls);
return "signature-callback/index";
}
}

Note que agora também consideramos o estado Processing como normal. Com isso, podemos alterar a forma que os documentos serão mostrados.

Em .NET, alteraríamos a view de Razor da seguinte maneira:

@using Lacuna.RestPki.Api
@using Lacuna.RestPki.Client
@model SignatureSession
<h2>Signed documents</h2>
<ul>
@foreach (var document in Model.Documents)
{
<li>
@if (document.Status == DocumentStatus.Completed)
{
<a href="@document.SignedFile.Url">@document.SignedFile.Name</a>
}
else
{
@document.OriginalFile.Name
<text> (processing)</text>
}
</li>
}
</ul>

Em PHP, alteraríamos o lado do cliente da seguinte maneira:

<h2>Signed documents</h2>
<ul>
<?php for ($i = 0; $i < count($session->documents); $i++) {
$document = $session->documents[$i]; ?>

<li>
<?php if ($document->status == DocumentStatus::COMPLETED) { ?>
<a href="<?= $document->signedFile->location ?>"><?= $document->signedFile->name ?></a>
<?php } else { ?>
<?= $document->originalFile->name ?>
<text> (processing)</text>
<?php } ?>
</li>
<?php } ?>
</ul>

Em Java, alteraríamos a view Thymeleaf do Spring da seguinte maneira:

<h2>Signed documents</h2>
<ul>
<li th:each="document : ${session.getDocuments()}">
<a th:if="${signedFileUrls.containsKey(document.getId())}" th:href="${signedFileUrls.get(document.getId())}">
<span th:text="${document.getSignedFile().getName()}"/>
</a>
<span th:unless="${signedFileUrls.containsKey(document.getId())}">
<span th:text="${document.getOriginalFile().getName()}"/> (processing)
</span>
</li>
</ul>

Note que renderizamos cada item da lista de maneira diferente baseado no estado do documento. O cliente PHP só expõe o link do arquivo assinado como location, nome obsoleto do campo url (veja Implementando o tratamento de retorno).

Ver em Markdown