# Electronic Signature Module

This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](https://developer.incode.com/docs/web-sdk-reference). Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade.

Full rollout to all clients still TBD.

The Electronic Signature module handles eIDAS-aligned electronic signing flows: render documents to be signed, collect compliance consents, capture the signature, and finalize. Three variants exist — base AES, Advanced Electronic Signature (AE), and Qualified Electronic Signature (QE) — that share a single state machine and manager API.

## Variants

`ae-signature` and `qe-signature` are thin wrappers around `electronic-signature`:

| Module | Manager factory | Consent keys |
| --- | --- | --- |
| `@incodetech/core/electronic-signature` | `createElectronicSignatureManager` | Caller-provided |
| `@incodetech/core/ae-signature` | `createAeSignatureManager` | `AE_CONSENT_KEYS` (3 keys) |
| `@incodetech/core/qe-signature` | `createQeSignatureManager` | `QE_CONSENT_KEYS` (5 keys) |

The wrappers hardcode `variant: 'ae'` or `'qe'` and re-export the same state machine, state types, and helpers from the base module (`AeSignatureState` is `ElectronicSignatureState`, etc.).

Web components: `<incode-electronic-signature>`, `<incode-ae-signature>`, `<incode-qe-signature>`. All three import paths register their own tag and ship their own CSS.

### Code Examples

```ts
// Base AES
import '@incodetech/web/electronic-signature';
import '@incodetech/web/electronic-signature/styles.css';

// Advanced Electronic Signature
import '@incodetech/web/ae-signature';
import '@incodetech/web/ae-signature/styles.css';

// Qualified Electronic Signature
import '@incodetech/web/qe-signature';
import '@incodetech/web/qe-signature/styles.css';
```

## Properties

| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `config` | `ElectronicSignatureConfig` | ❌ | Configuration options |
| `onFinish` | `() => void` | ❌ | Called when signing completes |
| `onError` | `(error: string) => void` | ❌ | Called when the user dismisses (`closed`) |

## Configuration

TypeScript

```typescript
type ElectronicSignatureConfig = {
  variant?: 'ae' | 'qe'; // Hardcoded by the AE/QE wrapper modules
  uploadDocument?: boolean;
  downloadDocument?: boolean;
};
```

| Option | Type | Required | Description |
| --- | --- | --- | --- |
| `variant` | `'ae' | 'qe'` | ❌ | Set automatically by the AE/QE wrapper modules. Omit for base AES. |
| `uploadDocument` | `boolean` | ❌ | Allow the user to upload a custom document to be signed. |
| `downloadDocument` | `boolean` | ❌ | Allow the user to download the signed document afterwards. |

### Consent keys

The user must check all required consent boxes before signing. Each variant defines its own keys (re-exported from the variant's module):

TypeScript

```typescript
const AE_CONSENT_KEYS = [
  'terms',
  'signElectronically',
  'signDisplayed',
] as const;

const QE_CONSENT_KEYS = [
  'issuance',
  'qesAcknowledgement',
  'qscdConfirmation',
  'termsAgreement',
  'documentsReviewed',
] as const;
```

Helpers from `@incodetech/core/electronic-signature` (also re-exported from the AE/QE wrappers): `getDefaultConsentChecks(variant)` returns a fresh `ConsentChecks` map for the given variant (`'ae' | 'qe'`); `areAllConsented(consents)` returns whether every key in that map is checked.

## State machine

`ElectronicSignatureState` is a discriminated union over `status`:

| Status | Description |
| --- | --- |
| `loading` | Fetching the documents to be signed. |
| `uploading` | User selects a document to upload (when `uploadDocument` is set). |
| `reviewing` | Document preview before upload confirmation. |
| `signing` | Documents shown; user toggles consent checkboxes. |
| `processing` | Server-side signing in progress. |
| `success` | Signing accepted (auto-finishes after 3s unless download flow). |
| `signError` | Signing failed; error screen shown for 3s then auto-finishes. |
| `finished` | Terminal success. |
| `closed` | User dismissed. |
| `error` | Recoverable upload/fetch-docs failure (Try Again). |

The `state.documents` array (when populated) carries the `ElectronicSignatureDocument[]` to render: `{ documentRef, documentUrl }`.

A few states carry additional fields beyond `documents`: `uploading` and `reviewing` add `fileName` (`reviewing` also adds `fileUrl`); `signing` adds `variant`, `consentChecks`, `allConsented`, and `viewingDocumentUrl` (set while `viewDocument()` is open); `success` adds `signedDocuments: { signed: boolean; signedDocumentUrl?: string }[]` and `downloadDocument`. The base AES endpoint returns a `signedDocumentUrl` per document; the QES endpoint acknowledges with `{ success: true }` and no document URL, so `signedDocumentUrl` is absent for QE signatures — check `signed` rather than assuming a URL is always present.

## API methods

| Method | Purpose |
| --- | --- |
| `load()` | Fetch documents. |
| `setConsent(name, checked)` | Toggle a consent checkbox by key. |
| `selectFile(fileName, fileData, fileUrl)` | Provide a custom document (when `uploadDocument` is `true`). |
| `replaceFile()` | Clear the previously selected file. |
| `confirmFile()` | Confirm document selection and proceed to signing. |
| `viewDocument(url)` / `closeDocumentView()` | Open / close the document preview. |
| `sign()` | Produce the signature once consents are checked. |
| `finish()` | Acknowledge `success` and finish. |
| `retry()` | After `error`, restart. |
| `close()` | Dismiss (transitions to `closed`). |

Plus the base lifecycle: `subscribe`, `getState`, `stop`. Unlike the face-capture and ID-capture managers, this manager has no `reset()` — create a new manager instance to start over.
