Evrotrust (eSIGN)

Capability: eSIGN

Market: Europe (Bulgaria, North Macedonia)

Business Capabilities

Use this connector to send one or multiple PDF documents to Evrotrust, an EU-qualified trust service provider (QTSP) used by the PCB banking profiles, for qualified electronic signing and to retrieve the signed results.

  • User signing (offline / user-sign) - the connector pushes the document to the signer's Evrotrust mobile app. The signer approves it there, optionally confirming with an OTP activation code.
  • Bank signing (online / bank-sign) - the bank signs the document automatically using its configured automated signing certificate, with no signer interaction.

Both modes work for a single document or a group of documents signed together. Signing is asynchronous: the connector returns a transactionID immediately and delivers the final signed result through a webhook once Evrotrust calls back. You can then poll signed PDFs for status and download them.

The connector also exposes a read-only lookup for the status of an Evrotrust one-time identification session.

Exposed Endpoints

All endpoints are served under the base path /api/esign/v1/evrotrust.

  • User-sign a document (mobile app): POST /document/user-sign
  • User-sign a group of documents: POST /document/group/user-sign
  • Activate user signing with OTP: POST /document/user-sign/activate
  • Activate group user signing with OTP: POST /document/group/user-sign/activate
  • Bank-sign a document (automated): POST /document/bank-sign
  • Bank-sign a group of documents: POST /document/group/bank-sign
  • Get document signing status: GET /document/status?transactionId={id}
  • Get group signing status: GET /document/group/status?transactionId={id}
  • Download a signed document (raw PDF): GET /document/download/{transactionId}
  • List signed documents of a group: GET /document/group/download/{transactionId}
  • Download one signed group document (raw PDF): GET /document/group/download/file/{fileId}
  • Get one-time identification status: GET /identification/status
  • Evrotrust signing callback (vendor to connector): POST /callback/document/{readyPath}

Required Request Headers

Every caller-facing endpoint requires the following headers. Evrotrust invokes the callback endpoint, which does not require them.

  • DC-Client-Id (required) - Client profile identifier that selects the Evrotrust credentials and configuration to use, for example pcb-bg or pcb-mk.
  • DC-Webhook-Id (required for sign endpoints) - Webhook destination for the signing result. Must match an id configured in webhookConfig.endpoints for the selected profile, for example bg-dev, bg-uat, or mk-dev.

Vault Configuration

The connector resolves configuration per client profile, selected by the DC-Client-Id header.

  • evrotrustVendorApiUrl - Base URL of the Evrotrust vendor API.
  • evrotrustVendorNumber - Evrotrust vendor number identifying the account.
  • evrotrustVendorApiKey - Secret API key. The connector SHA-256 hashes it and uses it as the HMAC key for request authentication.
  • evrotrustPublicKey - Evrotrust public key sent with sign requests.
  • evrotrustPrivateKey - Private key (PEM) that decrypts downloaded signed documents.
  • evrotrustCallbackUrl - URL Evrotrust calls back when a signing operation completes.
  • evrotrustStatusLabels - Map of status code to human-readable label, added to status and callback payloads.
  • evrotrustSignDefaults (optional) - Per-profile default sign parameters (coverage, certificateType, preview, bioRequired, expireSeconds). Request values always take precedence.
  • evrotrustAutomatedSignCertId (optional) - The bank's automated signing certificate id. When set, you can omit users on bank-sign requests.

Platform infrastructure values (app.cma.url, app.idp.url, app.vault.secrets.engine) are set in application.properties. app.cma.url is required for storage interaction: the transaction routing table and signed-document blob storage.

Authentication

Data Core does not require the caller to pass a vendor access token. The connector authenticates requests to Evrotrust server-side:

  • It computes an HMAC-SHA256 signature over the exact JSON body it sends, keyed by SHA-256(evrotrustVendorApiKey), and passes it in the Authorization header of each vendor call.
  • Multipart sign requests sign the data JSON part. JSON requests sign the raw serialized body byte-for-byte to keep the HMAC aligned with what Evrotrust receives.

The only headers the caller provides are DC-Client-Id (profile selection) and DC-Webhook-Id (result routing).

Signing Flow

Signing is asynchronous:

  1. The caller sends a sign request (/document/user-sign, /document/bank-sign, or their /group/ variants) with DC-Client-Id and DC-Webhook-Id.
  2. The connector calls Evrotrust and immediately returns a transactionID (offline) or a threadID plus transactions[] (online). It persists a routing entry that maps transactionID to webhookId, clientId, and externalReference.
  3. For user-sign, the signer completes signing in the Evrotrust app. When OTP is required, the caller submits it through /document/user-sign/activate.
  4. When signing finishes, Evrotrust calls POST /callback/document/{readyPath}. The connector looks up the routing entry, enriches the payload with a human-readable statusLabel, dispatches a webhook to the platform (evrotrustEsignWebhook), then removes the routing entry.
  5. The caller polls GET /document/status and downloads the signed PDF(s).

Request Structures and Samples

POST /api/esign/v1/evrotrust/document/user-sign

Sends a single PDF to the signer's Evrotrust mobile app. Returns a transactionID.

Copy
{
    "externalReference": "loan-4821",
    "documentBase64": "JVBERi0xLjcKJ...base64 PDF...",
    "filename": "loan-agreement.pdf",
    "referenceId": "1a2b3c4d-...",
    "document": {
        "description": "Loan agreement",
        "coverage": 1,
        "preview": 0,
        "certificateType": 1
    },
    "user": {
        "identificationNumber": "7501011234",
        "firstName": "Ivan",
        "lastName": "Petrov",
        "phone": "+359888123456",
        "country": "BG",
        "email": "ivan.petrov@mail.com",
        "language": "bg"
    }
}

user.email is optional. When set, Evrotrust emails the signed document to that address after signing. Omit it to suppress that email.

Copy
{ "transactionID": "b4d69ea1-4759-4276-9390-d34365ee8295" }

POST /api/esign/v1/evrotrust/document/bank-sign

Signs a single PDF automatically with the bank certificate. You can omit users when evrotrustAutomatedSignCertId is configured for the profile.

Copy
{
                "externalReference": "stmt-9931",
                "documentBase64": "JVBERi0xLjcKJ...base64 PDF...",
                "filename": "statement.pdf",
                "document": { "description": "Account statement", "coverage": 1 },
                "users": [ { "automatedSignCertID": "cert-abc-123" } ],
                "bioRequired": 0
        }
{
                "threadID": "6f0e...",
                "transactions": [
                { "transactionID": "b4d69ea1-4759-4276-9390-d34365ee8295", "automatedSignCertID": "cert-abc-123" }
                ]
        }

POST /api/esign/v1/evrotrust/document/group/user-sign

Sends multiple PDFs as one signable group. groupDescription is required.

Copy
{
                "externalReference": "onboarding-771",
                "groupDescription": "Account opening pack",
                "referenceId": "1a2b3c4d-...",
                "coverage": 1,
                "certificateType": 1,
                "user": { "identificationNumber": "7501011234", "country": "BG" },
                "documents": [
                {
                "base64": "JVBERi0xLjcK...doc1...",
                "filename": "terms.pdf",
                "metadata": { "description": "General terms", "optional": 0, "preview": 0 }
                },
                {
                "base64": "JVBERi0xLjcK...doc2...",
                "filename": "gdpr.pdf",
                "metadata": { "description": "GDPR consent", "optional": 1, "preview": 0 }
                }
                ]
        }

metadata.optional: 0 means the signer must sign, 1 means the signer may skip. Defaults to 0.

Copy
{ "transactionID": "77c1e0a2-..." }

POST /api/esign/v1/evrotrust/document/user-sign/activate

Submits the OTP the signer entered to confirm signing. The group variant (/document/group/user-sign/activate) uses the same shape.

Copy
{ "transactionId": "b4d69ea1-4759-4276-9390-d34365ee8295", "activationCode": "482913" }
Copy
{ "transactionID": "b4d69ea1-4759-4276-9390-d34365ee8295", "status": 1, "statusDescription": "Signed" }

Evrotrust may answer a successful activation with an empty body. The connector then returns just the transactionID.

GET /api/esign/v1/evrotrust/document/status

Copy
{
                "transactionID": "b4d69ea1-4759-4276-9390-d34365ee8295",
                "status": 2,
                "statusLabel": "Signed",
                "signatureCount": 1,
                "isProcessing": 0
        }

GET /api/esign/v1/evrotrust/document/download/{transactionId}

Returns the signed PDF as raw application/pdf. The real filename, which may contain non-ASCII or Cyrillic characters, arrives in an RFC 6266 Content-Disposition header:

Copy
Content-Type: application/pdf
Content-Disposition: inline; filename="Obshti usloviya.pdf"; filename*=UTF-8''%D0%9E%D0%B1%D1%89%D0%B8%20%D1%83%D1%81%D0%BB%D0%BE%D0%B2%D0%B8%D1%8F.pdf

GET /api/esign/v1/evrotrust/document/group/download/{transactionId}

Returns a listing, one entry per signed PDF:

Copy
[
                { "name": "377608989971_OUT_SIGNED.pdf", "fileId": "c0ffee12-..." },
                { "name": "gdpr_SIGNED.pdf", "fileId": "dead10cc-..." }
        ]

Fetch each file with GET /document/group/download/file/{fileId} (raw application/pdf). Repeat listing calls return the same fileId values. A fileId stays downloadable until the external storage cleanup removes the stored blob. Afterwards, the connector returns 410 Gone.

POST /api/esign/v1/evrotrust/callback/document/{readyPath}

Evrotrust calls this endpoint, not the platform, when signing completes. The connector forwards the enriched result to the platform webhook and responds 204 No Content.

Copy
{
    "transactionID": "b4d69ea1-4759-4276-9390-d34365ee8295",
    "status": 2,
    "statusLabel": "Signed",
    "rejectReason": null,
    "automatedSignError": null
}

Error Codes

400 Bad Request - validation error (bean-validation constraint):

Copy
{
                "status": 400,
                "title": "Constraint Violation",
                "instance": "/esign/v1/evrotrust/document/user-sign",
                "timestamp": "2025-04-29T15:34:22Z",
                "errors": [
                { "pointer": "signDocOffline.request.externalReference", "detail": "must not be blank" }
                ]
        }

Other notable responses:

  • 400 Bad Request - Missing DC-Webhook-Id header; documentBase64 not valid base64; missing transactionId; identification lookup with neither referenceId nor externalReferenceId; users omitted while evrotrustAutomatedSignCertId is not configured.
  • 410 Gone - A group download fileId whose stored blob was removed by cleanup.
  • 502 Bad Gateway - Evrotrust returned no transactionID on sign, or no document bytes on download.