diff --git a/javascript/src/iframe/viamapi-iframe.js b/javascript/src/iframe/viamapi-iframe.js
index f96df4b886d368a0c367c60f74d09178c170cc67..06421ddc10d4f098559a4e891b9a51e509d1e9f6 100644
--- a/javascript/src/iframe/viamapi-iframe.js
+++ b/javascript/src/iframe/viamapi-iframe.js
@@ -365,6 +365,12 @@ async function executeRestfulFunction(type, that, fn, config, ...args) {
 
 window.executeRestfulFunction = executeRestfulFunction;
 
+const TRANSPARENT_PIXEL = new ImageData({
+  contentType: "image/png",
+  contentBase64:
+    "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" //1x1px transparent pixel
+});
+
 function loadIdentityInternal(identityKey, pinCode) {
   return new Penpal.Promise(result => {
     getIdentityFromLocalStorage(identityKey, pinCode)
@@ -1368,10 +1374,99 @@ const connection = Penpal.connectToParent({
 
       return encodeResponse("200", "", "Document signed");
     },
+    /**
+     * Checks the state of the vCard. Current states are "disabled" and "enabled".
+     * @param passportUUID
+     * @returns {Promise<{code: *, data: *, status: *}>}
+     */
+    async checkVCardState(passportUUID) {
+      const authenticationPublicKey = localStorage.getItem(
+        "authenticatedIdentity"
+      );
+
+      if (
+        !authenticationPublicKey ||
+        !window.loadedIdentities[authenticationPublicKey] ||
+        !extendPinCodeTtl(authenticationPublicKey)
+      ) {
+        return encodeResponse("400", "", "Identity not authenticated");
+      }
+
+      let vCardImageClaimValue;
+
+      const vCardImageClaimName = "vCardImage";
+      const defaultTagName = "notag";
+
+      const vCardClaimResponse = await executeRestfulFunction(
+        "private",
+        window.viamApi,
+        window.viamApi.entityGetClaim,
+        null,
+        vCardImageClaimName,
+        defaultTagName,
+        passportUUID
+      );
+
+      // You may not have vCard image claim, but backend will still return blank image from passportGetVCardImage
+
+      // if (vCardClaimResponse.code !== "200") {
+      //   return encodeResponse("400", "", vCardClaimResponse.status);
+      // }
+
+      if (vCardClaimResponse.code === "200") {
+        vCardImageClaimValue = vCardClaimResponse.data;
+      }
+
+      if (
+        vCardImageClaimValue &&
+        "state" in vCardImageClaimValue
+      ) {
+        return encodeResponse("200", vCardImageClaimValue.state, "OK");
+      }
+
+      return encodeResponse("200", "enabled", "OK");
+    },
+    /**
+     * 
+     * @param passportUUID
+     * @param documentUUID
+     * @param documentContentType
+     * @param signatureData -
+     * @returns {Promise<{code: *, data: *, status: *}>}
+     *
+// Image position in pixels
+message Position {
+  int32 left = 1; // x
+  int32 top = 2; // y
+}
+
+     // Image size in pixels
+     message Size {
+  uint32 width = 1;
+  uint32 height = 2;
+}
+
+     // Image size in pixels
+     message Bounds {
+  int32 left = 1; // x
+  int32 top = 2; // y
+  uint32 width = 3;
+  uint32 height = 4;
+}
+message SignatureData {
+  ImageData signatureImageData = 1;
+  Bounds signatureBounds = 2;
+  uint32 pageNumber = 3;
+  Size pageSize = 4;
+}
+     * 
+     */
     signDocumentJava: async (
       passportUUID,
       documentUUID,
-      documentContentType
+      documentContentType,
+      signatureData = null,
+      qrCodeUrl = null
     ) => {
       const authenticationPublicKey = localStorage.getItem(
         "authenticatedIdentity"
@@ -1385,6 +1480,80 @@ const connection = Penpal.connectToParent({
         return encodeResponse("400", "", "Identity not authenticated");
       }
 
+
+      // Get vCard and QR Code Coordinates
+
+      let vCardImageData;
+      let vCardImageClaimValue;
+
+      let qrCodeImageData;
+      let qrCodeCoordinates = {fromL: -1, fromR: -1, toL: -1, toR: -1};
+
+      if (signatureData) {
+        const vCardImageClaimName = "vCardImage";
+        const defaultTagName = "notag";
+
+        const vCardClaimResponse = await executeRestfulFunction(
+          "private",
+          window.viamApi,
+          window.viamApi.entityGetClaim,
+          null,
+          vCardImageClaimName,
+          defaultTagName,
+          passportUUID
+        );
+        // if (vCardClaimResponse.code !== "200") {
+        //   return encodeResponse("400", "", vCardClaimResponse.status);
+        // }
+
+        if (vCardClaimResponse.code === "200") {
+          vCardImageClaimValue = vCardClaimResponse.data;
+        }
+
+        if (
+          vCardImageClaimValue &&
+          "state" in vCardImageClaimValue &&
+          vCardImageClaimValue.state === "disabled"
+        ) {
+          vCardImageData = TRANSPARENT_PIXEL;
+        } else {
+          const vCardImageResponse = await executeRestfulFunction(
+            "private",
+            window.viamApi,
+            window.viamApi.passportGetVCardImage,
+            null,
+            passportUUID
+          );
+
+          if (vCardImageResponse.code !== "200") {
+            return encodeResponse("400", "", vCardImageResponse.status);
+          }
+          vCardImageData = new ImageData(vCardImageResponse.data.Image);
+          if (vCardImageData.contentType !== "image/png") {
+            return encodeResponse(
+              "400",
+              "",
+              "Content type of vCard must be 'image/png'"
+            );
+          }
+
+          if (qrCodeUrl) {
+            qrCodeCoordinates = vCardImageResponse.data.QRCodeCoordinates;
+            const qrCodeBase64Content = await generateQrCode(qrCodeUrl);
+            qrCodeImageData = new ImageData({
+              contentType: "image/png",
+              content: qrCodeBase64Content
+            });
+          }
+        }
+
+        // Fill signature data onject
+
+        signatureData.signatureImageData = vCardImageData;
+      }
+
+      // Generate certificate chain
+
       const certResponse = await getCertificateForPassport(passportUUID, true);
 
       if (certResponse.code !== "200") {
@@ -1416,6 +1585,8 @@ const connection = Penpal.connectToParent({
 
       passportChain.reverse();
 
+      // eventually convert document
+
       const pdfContentType = "application/pdf";
 
       if (documentContentType !== pdfContentType) {
@@ -1433,6 +1604,8 @@ const connection = Penpal.connectToParent({
         }
       }
 
+      // Sign document
+
       const signResponse = await executeRestfulFunction(
         "private",
         window.viamApi,
@@ -1442,7 +1615,10 @@ const connection = Penpal.connectToParent({
         passportChain,
         passportUUID,
         documentUUID,
-        pdfContentType
+        pdfContentType,
+        signatureData,
+        qrCodeImageData,
+        qrCodeCoordinates
       );
       if (signResponse.code !== "200") {
         return encodeResponse("400", "", signResponse.status);
@@ -1496,6 +1672,9 @@ const connection = Penpal.connectToParent({
       let vCardImageData;
       let vCardImageClaimValue;
 
+      let qrCodeImageData;
+      let qrCodeCoordinates = {fromL: -1, fromR: -1, toL: -1, toR: -1};
+
       const vCardImageClaimName = "vCardImage";
       const defaultTagName = "notag";
 
@@ -1516,19 +1695,12 @@ const connection = Penpal.connectToParent({
         vCardImageClaimValue = vCardClaimResponse.data;
       }
 
-      let qrCodeImageData;
-      let qrCodeCoordinates = { fromL: -1, fromR: -1, toL: -1, toR: -1 };
-
       if (
         vCardImageClaimValue &&
         "state" in vCardImageClaimValue &&
         vCardImageClaimValue.state === "disabled"
       ) {
-        vCardImageData = new ImageData({
-          contentType: "image/png",
-          contentBase64:
-            "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" //1x1px transparent pixel
-        });
+        vCardImageData = TRANSPARENT_PIXEL;
       } else {
         const vCardImageResponse = await executeRestfulFunction(
           "private",
@@ -1538,8 +1710,6 @@ const connection = Penpal.connectToParent({
           passportUUID
         );
 
-        console.log(vCardImageResponse);
-
         if (vCardImageResponse.code !== "200") {
           return encodeResponse("400", "", vCardImageResponse.status);
         }
@@ -1548,7 +1718,7 @@ const connection = Penpal.connectToParent({
           return encodeResponse(
             "400",
             "",
-            "Content type of vCard mmust be 'image/png'"
+            "Content type of vCard must be 'image/png'"
           );
         }
 
@@ -1639,8 +1809,6 @@ const connection = Penpal.connectToParent({
 
       passportChain.reverse();
 
-      console.log(qrCodeImageData);
-      console.log(qrCodeCoordinates);
 
       const signVCardResponse = await executeRestfulFunction(
         "private",
@@ -1759,6 +1927,76 @@ const connection = Penpal.connectToParent({
 
       return encodeResponse("200", response.data, "Document created");
     },
+    getVcardWithQrCode: async (passportUUID, QRCodeContent = null) =>{
+      //TODO: IMPLEMENT QR CODE backend method needed
+      const authenticationPublicKey = localStorage.getItem(
+        "authenticatedIdentity"
+      );
+
+      if (
+        !authenticationPublicKey ||
+        !window.loadedIdentities[authenticationPublicKey] ||
+        !extendPinCodeTtl(authenticationPublicKey)
+      ) {
+        return encodeResponse("400", "", "Identity not authenticated");
+      }
+
+      let vCardImageData;
+      let vCardImageClaimValue;
+
+      const vCardImageClaimName = "vCardImage";
+      const defaultTagName = "notag";
+
+      const vCardClaimResponse = await executeRestfulFunction(
+        "private",
+        window.viamApi,
+        window.viamApi.entityGetClaim,
+        null,
+        vCardImageClaimName,
+        defaultTagName,
+        passportUUID
+      );
+
+      if (vCardClaimResponse.code === "200") {
+        vCardImageClaimValue = vCardClaimResponse.data;
+      }
+
+      if (
+        vCardImageClaimValue &&
+        "state" in vCardImageClaimValue &&
+        vCardImageClaimValue.state === "disabled"
+      ) {
+        //No image data if the user have disabled vCard for this profile.
+        vCardImageData = null;
+
+        // vCardImageData = new ImageData({
+        //   contentType: "image/png",
+        //   contentBase64:
+        //     "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=" //1x1px transparent pixel
+        // });
+      } else {
+        const vCardImageResponse = await executeRestfulFunction(
+          "private",
+          window.viamApi,
+          window.viamApi.passportGetVCardImage,
+          null,
+          passportUUID
+        );
+
+        if (vCardImageResponse.code !== "200") {
+          return encodeResponse("400", "", vCardImageResponse.status);
+        }
+        vCardImageData = new ImageData(vCardImageResponse.data.Image);
+        if (vCardImageData.contentType !== "image/png") {
+          return encodeResponse(
+            "400",
+            "",
+            "Content type of vCard mmust be 'image/png'"
+          );
+        }
+      }
+      return  encodeResponse("200",vCardImageData, 'vCard got');
+    },
     documentPutDocument: async (
       passportUUID,
       resourceid,
diff --git a/javascript/src/utilities/signingUtilities.js b/javascript/src/utilities/signingUtilities.js
index ec255299e58fe5b77311be8f3a128bd646f22c31..20f64f0d273ceeb9fcc92c1542882b324fb6b699 100644
--- a/javascript/src/utilities/signingUtilities.js
+++ b/javascript/src/utilities/signingUtilities.js
@@ -1495,6 +1495,9 @@ export class ImageData {
     this.content = null; // Uint8Array: decoded content
     this.contentBase64 = null; // string: base64 encoded content
 
+    if (typeof parameters === "string" || parameters instanceof String) {
+      this.fromDataURL(parameters);
+    } else
     if (typeof parameters === "object") {
       this.fromParameters(parameters);
     }
@@ -1517,13 +1520,24 @@ export class ImageData {
     this.getContentBase64();
   }
 
-  //fromDataURL()
+  fromDataURL(dataURL) {
+    if (dataURL.startsWith("data:")) {
+      const idx = dataURL.indexOf(";base64,");
+      if (idx > 0) {
+        this.contentType = dataURL.substring(5, idx); // 5 = len("data:")
+        this.contentBase64 = dataURL.substring(idx + 8); // 8 = len(";base64,")
+      }
+    }
+  }
   //fromContentTypeAndContentAsByteArray()
 
   toDataURL() {
     return "data:" + this.contentType + ";base64," + this.getContentBase64();
   }
 
+  /**
+   * @returns {ByteArray}
+   */
   getContent() {
     if (!this.content) {
       if (this.contentBase64) {
@@ -1533,6 +1547,9 @@ export class ImageData {
     return this.content;
   }
 
+  /**
+   * @returns {String}
+   */
   getContentBase64() {
     if (!this.contentBase64) {
       if (this.content) {