跳至內容

嵌入式簽署

<bf-signing> 會在您的頁面中以沙箱 iframe 轉譯 Bona Fide 的簽署頁面,依文件調整其大小,並以 DOM 事件回報簽署人的操作。它不依賴任何架構;另外也隨附輕量的 React 與 Vue 包裝元件。

  1. 使用 delivery: "embedded" 建立信封,這樣就不會寄送電子郵件給收件者。

  2. 在簽署人開啟頁面時,於您的伺服器上核發工作階段,並將您網站的來源加入 allowedOrigins。嵌入的頁面會拒絕與任何未列出的父頁面通訊。

    // Your backend (never expose the API key to the browser)
    const res = await fetch(`https://api.bonafidesign.com/v1/envelopes/${envelopeId}/sessions`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ recipient: recipientId, mode: 'embedded', allowedOrigins: ['https://app.example.com'] }),
    });
    const { token } = await res.json(); // 'bfs_…', single-use, 10 minutes by default
  3. 使用權杖轉譯該元素。

    <script type="module" src="https://js.bonafidesign.com/v1"></script>
    <bf-signing session="bfs_…" theme="auto" min-height="480" max-height="90vh"></bf-signing>
    <script>
    const el = document.querySelector('bf-signing');
    el.addEventListener('completed', (e) => {
    // e.detail = { type: 'completed', envelope: 'env_…' }
    window.location.href = '/onboarding/next';
    });
    el.addEventListener('session_expiring', () => refreshSession());
    el.addEventListener('error', (e) => console.error(e.detail.code, e.detail.message));
    </script>
  4. 在您的伺服器上確認結果。 請將瀏覽器事件僅視為介面訊號,並以 envelope.completed Webhook(或 GET /v1/envelopes/{id})作為最終結果的依據。

屬性(React / Vue prop) 預設值 說明
session bfs_… 權杖。變更後會重新載入框架
base-url(baseUrl) https://sign.bonafidesign.com/s/ 該部署的託管簽署路由
theme auto auto、light 或 dark
locale 傳遞給簽署頁面
min-height、max-height(minHeight、maxHeight) 480、90vh 像素或 vh。框架會在兩者之間隨文件增高,超過後在內部捲動
timeout 30000 等待頁面載入的毫秒數,逾時後會觸發代碼為 load_timeout 的 error
frame-title Document signing iframe 的無障礙標題

此元素還有一個 reload() 方法,例如可在核發新的工作階段後呼叫。

事件會向上傳遞、跨越 Shadow Root,並在 event.detail 中攜帶承載。bf-event 會針對所有事件觸發。

事件 detail
ready { type: 'ready' }:簽署頁面已載入
field_completed { type, field }:某個欄位已填寫
signed { type, recipient }:此收件者已提交
completed { type, envelope }:信封已完成
declined { type, reason? }
session_expiring { type, expiresAt }:請盡快核發新的工作階段
error { type, code, message },包括 load_timeout 和 invalid_base_url

React 的 prop 為 onReady、onFieldCompleted、onSigned、onCompleted、onDeclined、onSessionExpiring、onError 和 onEvent;Vue 則會發出與事件同名的事件(@completed、@session_expiring 等)以及 event。

  • 權杖透過 iframe 的 URL 片段(#session=…)傳遞,片段絕不會送達伺服器,也不會出現在 Referer 標頭中。簽署頁面讀取權杖後,會將其從 URL 和瀏覽記錄中移除,並交換為保存在記憶體中的存取權杖。完全不使用 Cookie。
  • 此 iframe 位於沙箱中(allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads),並設定了 referrerpolicy="strict-origin"。
  • 只有當訊息來自該元素本身的 iframe,而且來自 base-url 的來源,而且能剖析為具命名空間的 bona-fide.embed/1 訊息時,您的頁面才會接受。其他所有訊息都會被忽略。
  • 簽署頁面只會將訊息傳送到您的確切來源(絕不使用 *),而且只有在該來源列於工作階段的 allowedOrigins 中時才會傳送。API 也會拒絕嵌入式工作階段來自未獲允許來源的呼叫。