Portal flow

This integration pattern is suitable for senders who want to create a signature job in portal flow. The signer logs in to the signing portal, signs the document, and the sender will then be able to poll for a status and retrieve the signed document. This scenario is designed to support a flow where it is necessary to obtain signatures from more than one signer.

To ease the integration, we provide C# and Java libraries. If you are creating your own client, you will have to interact directly with the API. The message format of the API is XML, and relevant types can be found in portal.xsd.

Flytskjema for portalintegrasjon

Flow chart for signing in portal flow: The chart shows that a sender creates a signature job, starts polling, signers signing the job, a status update is fetched by polling by the sender, followed by downloading the signed document. If you send only one job to one signer, please disregard the first “steg 4”-section. Solid lines show user flow and dashed lines shows requests to and responses from the API.

Having problems integrating?

Tip

Remember that if you are having problems creating a job in a portal signature flow, you can always get in touch with a developer on Github:

Get help for your C# integration here.

Step 1: Create signature job

ClientConfiguration clientConfiguration = null; //As initialized earlier
var portalClient = new PortalClient(clientConfiguration);

var documentsToSign = new List<Document>
{
    new Document(
        "Document title",
        FileType.Pdf,
        @"C:\Path\ToDocument\File.pdf"
    )
};

var signers = new List<Signer>
{
    new Signer(new PersonalIdentificationNumber("00000000000"), new NotificationsUsingLookup()),
    new Signer(new PersonalIdentificationNumber("11111111111"), new Notifications(
        new Email("email1@example.com"),
        new Sms("999999999"))),
    new Signer(new ContactInformation {Email = new Email("email2@example.com")}),
    new Signer(new ContactInformation {Sms = new Sms("88888888")}),
    new Signer(new ContactInformation
    {
        Email = new Email("email3@example.com"),
        Sms = new Sms("77777777")
    })
};

var portalJob = new Job("Job title", documentsToSign, signers, "myReferenceToJob");

var portalJobResponse = await portalClient.Create(portalJob);

Note

You may identify the signature job’s signers by personal identification number IdentifiedByPersonalIdentificationNumber or contact information. When identifying by contact information, you may choose between instantiating a PortalSigner using IdentifiedByEmail, IdentifiedByMobileNumber or IdentifiedByEmailAndMobileNumber.

The signer

Before starting this chapter, please read up on Addressing signers and Notifications and contact details. Signers can be addressed and notified in different ways.

Adressing the signer

//This functionality exists in C#, but the example has not been generated yet.

Other settings

Order

The order attribute on signer is used to specify the order of the signers. In the example above, the signature job will only be available to the signers with order = "1". Once signed, the job becomes available to those with order = "2", and for the signer with order = "3" when those with order = "2" have signed.

Availability

The element availability is used to control the period of time a signature job is available to the signer(s).

<availability>
    <activation-time>2016-02-10T12:00:00+01:00</activation-time>
    <available-seconds>864000</available-seconds>
</availability>

The time specified in activation-time indicates when the job is activated, and the first signers are given the opportunity to sign the job. The duration specified in available-seconds applies to all signers. That is, all signers will have the same time to sign or reject the job from it becomes available to them. Thus, this period applies to each set of signers with the same order.

For example, enter 345600 seconds (4 days) for signers with an order:

  1. Signers with order = 1 get 4 days from `` activation-time`` to sign.

  2. Signers with order = 2 will have the document made available immediately when all signers with order = 1 have signed. They will then have 4 days from the time signature job is made available.

Note

If you omit availability, the job will be activated immediately, and the job will be available for a maximum of 30 days for each set of order grouped signers.

Important

A signature job expires and stops if at least one signer does not sign within their time period when the job is available.

Important

Jobs that specify greater available-seconds than 7,776,000 seconds (90 days) are rejected.

Identifier in the signed document

The element identifier-in-signed-documents is used to specify how signers are to be identified in the signed documents. Allowed values are PERSONAL_IDENTIFICATION_NUMBER_AND_NAME, DATE_OF_BIRTH_AND_NAME and NAME, but not all are valid for all types of signature jobs and senders. For more information, see How are signers identified in a signed document?.

Note

You can specify a signature type and required authentication level. If signature type or required authentication level is omitted, default values will be set as specified by Signature type and Security level.

List<Document> documentsToSign = null; //As initialized earlier
var signers = new List<Signer>
{
    new Signer(new PersonalIdentificationNumber("00000000000"), new NotificationsUsingLookup())
    {
        SignatureType = SignatureType.AdvancedSignature
    }
};

var job = new Job(documentsToSign, signers, "myReferenceToJob")
{
    AuthenticationLevel = AuthenticationLevel.Four
};

Note

Note that only public organizations can do NotificationsUsingLookup.

Step 2: Get status changes

To find out what the status of the signature jobs you have created, you must periodically send requests to the signature service (polling). As a sender, you need to check to which job the update applies to, update the status in your system and then confirm it.

The response to this call will be one of two things:

  • status update: a 200 OK response that contains information about new status for one job. This is defined by the element portal-signature-job-status-change-response.

  • no update available: If there are no updates to your signature jobs, you will receive a 204 No Content response.

Note

The next allowed polling time will be 10 minutes in the production environment if the queue is empty, while for test environments it will be between 5 and 30 seconds. In practice, the time for the next permitted polling request will be immediate as long as one receives a response that includes a status update.

The following example shows how this can be handled and examples of data to extract from a change response.

Note

Status updates you download will disappear from the queue. This allows you to ask for status updates in parallel, and you will not receive the same status update twice. It is therefore important that you confirm receipt of each status update as soon as possible, because if an error still occurs during transmission or processing, the receipt will be queued again after 10 minutes.

Responses will always include the next permitted poll time, which tells you when you can make the next request, and it is important that this time is met. If you send a request before this time has passed, you will receive a 429 Too Many Requests response. This will also contain a next permitted poll time, containing a new time.

PortalClient portalClient = null; //As initialized earlier

// Repeat the polling until signer signs the document, but ensure to do this at a
// reasonable interval. If you are processing the result a few times a day in your
// system, only poll a few times a day.
var change = await portalClient.GetStatusChange();

switch (change.Status)
{
    case JobStatus.NoChanges:
        //Queue is empty. Additional polling will result in blocking for a defined period.
        break;
    case JobStatus.Failed:
    case JobStatus.InProgress:
    case JobStatus.CompletedSuccessfully:
    {
        var signatureJobStatus = change.Status;
        var signatures = change.Signatures;
        var signatureOne = signatures.ElementAt(0);
        var signatureOneStatus = signatureOne.SignatureStatus;
        break;
    }
}

var pollingWillResultInBlock = change.NextPermittedPollTime > DateTime.Now;
if (pollingWillResultInBlock)
{
    //Wait until next permitted poll time has passed before polling again.
}

//Confirm the receipt to remove it from the queue
await portalClient.Confirm(change.ConfirmationReference);

Step 3: Get signed documents

PortalClient portalClient = null; //As initialized earlier
var jobStatusChanged = await portalClient.GetStatusChange();

//Get PAdES:
var pades = await portalClient.GetPades(jobStatusChanged.PadesReference);

Specifying queues

An important and necessary feature for organizations using more than one application to create signature jobs through the API. It enables an application to retrieve status changes independent of other applications.

The pollingQueue property is applicable for jobs where StatusRetrievalMethod == POLLING, and is used to assign jobs to a specified queue which is then used to retrieve status changes. If your organization is using more than one application/integration to access our API, we strongly recommend using a separate queue for each one. This is to ensure that one does not retrieve the others’ status updates. This may result in missing status updates for jobs in one of the applications, which in turn will result in a poor user experience. Only use the default queue, eg. not specifying a queue, when only one of your applications access our API.

To specify a queue, set pollingQueue through when constructing a Sender. Please note that the same sender must be specified when polling to retrieve status changes. The Sender can be set globally in ClientConfiguration or on every job.

PortalClient portalClient = null; //As initialized earlier

var organizationNumber = "123456789";
var sender = new Sender(organizationNumber, new PollingQueue("CustomPollingQueue"));

var documentsToSign = new List<Document>
{
    new Document(
        "Document title",
        FileType.Pdf,
        @"C:\Path\ToDocument\File.pdf"
    )
};

var signers = new List<Signer>
{
    new Signer(new PersonalIdentificationNumber("00000000000"), new NotificationsUsingLookup())
};

var portalJob = new Job("Job title", documentsToSign, signers, "myReferenceToJob", sender);

var portalJobResponse = await portalClient.Create(portalJob);

var changedJob = await portalClient.GetStatusChange(sender);

Delete documents

After receiving a status change, the documents can be deleted as follows:

//This functionality exists in C#, but the example has not been generated yet.