Skip to main content

Tổng quan

econtractid hỗ trợ nhúng giao diện trực tiếp vào website của bên thứ ba thông qua <iframe>. Người dùng không cần rời khỏi hệ thống hiện tại mà vẫn có thể:
  • Xem danh sách hồ sơ / hợp đồng
  • Xem chi tiết và xem PDF hợp đồng
  • Thực hiện ký số (ký đơn giản, ký ảnh, ký USB Token, ký Cloud HSM)
  • Xử lý công việc liên quan đến hợp đồng
Phương thức này phù hợp cho các hệ thống muốn tích hợp nhanh giao diện econtractid mà không cần phát triển lại UI.

Luồng hoạt động


Bước 1: Lấy Access Token

Có 2 cách để lấy accessToken từ hệ thống econtractid:
Đăng nhập bằng tài khoản người dùng (username + password):
POST https://api.econtractid.vn/api/auth/login
Content-Type: application/json

{
  "username": "user@example.com",
  "password": "your_password"
}
Response thành công:
{
  "statusCode": 200,
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIs...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
    "expiresIn": 3600
  }
}
TrườngKiểuMô tả
usernamestringEmail hoặc tên đăng nhập
passwordstringMật khẩu tài khoản
Phù hợp khi hệ thống bên thứ ba quản lý trực tiếp thông tin đăng nhập của người dùng trên econtractid.
Access Token có hiệu lực 1 giờ. Khi token hết hạn, cần gọi API refresh hoặc login lại để lấy token mới và cập nhật lại iframe.
Xem chi tiết về xác thực tại Xác thực & Phân quyền API.

Bước 2: Tạo URL nhúng

Tạo URL truy cập econtractid kèm accessToken dưới dạng query parameter at:
https://app.econtractid.com/{đường-dẫn}?at={accessToken}

Các đường dẫn phổ biến

Đường dẫnMô tả
/dashboardTrang tổng quan
/ho-soDanh sách hồ sơ hợp đồng
/ho-so/{id}Chi tiết một hồ sơ cụ thể
/xu-ly-cong-viecDanh sách công việc cần xử lý
/ky-so/{id}Trang ký số hợp đồng
Ví dụ URL đầy đủ:
https://app.econtractid.com/ho-so?at=eyJhbGciOiJIUzI1NiIs...
Để kiểm tra nhanh, bạn có thể đăng nhập hệ thống econtractid, lấy accessToken từ DevTools (Application → localStorage), sau đó mở trình duyệt mới (hoặc cửa sổ ẩn danh) và paste URL kèm accessToken để xác nhận hoạt động đúng.

Bước 3: Nhúng iframe vào website

HTML thuần

<iframe
  id="econtract-frame"
  src="https://app.econtractid.com/ho-so?at=YOUR_ACCESS_TOKEN"
  width="100%"
  height="800px"
  frameborder="0"
  style="border: 1px solid #ddd; border-radius: 8px; background: #fff;"
  allow="clipboard-read; clipboard-write"
>
</iframe>

Angular

// component.ts
import { Component, OnInit } from "@angular/core";
import { DomSanitizer, SafeResourceUrl } from "@angular/platform-browser";

@Component({
  selector: "app-econtract-embed",
  template: `
    <iframe
      id="econtract-frame"
      [src]="econtractIframeSrc"
      width="100%"
      height="800px"
      frameborder="0"
      style="border: 1px solid #ddd; border-radius: 8px; background: #fff;"
      allow="clipboard-read; clipboard-write"
    >
    </iframe>
  `,
})
export class EcontractEmbedComponent implements OnInit {
  econtractIframeSrc: SafeResourceUrl = "";

  constructor(private sanitizer: DomSanitizer) {}

  ngOnInit(): void {
    const accessToken = "eyJhbGciOiJIUzI1NiIs..."; // Lấy từ API login
    const baseUrl = "https://app.econtractid.com/ho-so";
    const url = `${baseUrl}?at=${accessToken}`;
    this.econtractIframeSrc =
      this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

React

import React, { useState, useEffect } from "react";

function EcontractEmbed() {
  const [iframeSrc, setIframeSrc] = useState("");

  useEffect(() => {
    // Gọi API login để lấy accessToken
    async function getToken() {
      const response = await fetch(
        "https://api.econtractid.vn/api/auth/login",
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            username: "user@example.com",
            password: "your_password",
          }),
        },
      );
      const data = await response.json();
      const accessToken = data.data.accessToken;
      setIframeSrc(`https://app.econtractid.com/ho-so?at=${accessToken}`);
    }
    getToken();
  }, []);

  if (!iframeSrc) return <div>Đang tải...</div>;

  return (
    <iframe
      id="econtract-frame"
      src={iframeSrc}
      width="100%"
      height="800px"
      frameBorder="0"
      style={{
        border: "1px solid #ddd",
        borderRadius: "8px",
        background: "#fff",
      }}
      allow="clipboard-read; clipboard-write"
    />
  );
}

export default EcontractEmbed;

Vue.js

<template>
  <iframe
    v-if="iframeSrc"
    id="econtract-frame"
    :src="iframeSrc"
    width="100%"
    height="800px"
    frameborder="0"
    style="border: 1px solid #ddd; border-radius: 8px; background: #fff;"
    allow="clipboard-read; clipboard-write"
  />
  <div v-else>Đang tải...</div>
</template>

<script setup>
import { ref, onMounted } from "vue";

const iframeSrc = ref("");

onMounted(async () => {
  const response = await fetch("https://api.econtractid.vn/api/auth/login", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      username: "user@example.com",
      password: "your_password",
    }),
  });
  const data = await response.json();
  const accessToken = data.data.accessToken;
  iframeSrc.value = `https://app.econtractid.com/ho-so?at=${accessToken}`;
});
</script>

Xử lý sự cố

Vấn đềNguyên nhânGiải pháp
Iframe hiển thị trang loginToken hết hạn hoặc không hợp lệKiểm tra lại token, gọi refresh hoặc login lại
Lỗi Refused to display in a frameDomain chưa được đăng kýLiên hệ hỗ trợ để đăng ký domain
Iframe trắng trốngCSP chặn iframeThêm frame-src vào CSP của website
Không ký được bằng USB TokenIframe chặn pluginSử dụng phương thức ký Cloud HSM hoặc ký ảnh thay thế
Token hết hạn liên tụcKhông có cơ chế refreshTriển khai auto-refresh token (xem mục Xử lý Token hết hạn)

Hỗ trợ

Nếu gặp vấn đề khi tích hợp, liên hệ đội ngũ hỗ trợ: