嵌入式签署
<bf-signing> 会在您的页面中以沙盒 iframe 渲染 Bona Fide 的签署页面,根据文档调整其尺寸,并以 DOM 事件的形式报告签署人的操作。它不依赖任何框架;同时附带轻量的 React 和 Vue 封装。
-
使用
delivery: "embedded"创建信封,这样就不会向收件人发送电子邮件。 -
在签署人打开页面时,在您的服务器上签发会话,并将您网站的源加入
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 -
使用令牌渲染该元素。
<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>import { BonaFideSigning } from '@bona-fide/embed/react';export function SignContract({ token }: { token: string }) {return (<BonaFideSigningsession={token}theme="auto"minHeight={480}maxHeight="90vh"onCompleted={(e) => console.log('envelope completed', e.envelope)}onDeclined={(e) => console.log('declined', e.reason)}onSessionExpiring={() => refreshSession()}onError={(e) => console.error(e.code, e.message)}/>);}<script setup lang="ts">import { BonaFideSigning } from '@bona-fide/embed/vue';defineProps<{ token: string }>();const done = (e: { envelope: string }) => console.log('envelope completed', e.envelope);</script><template><BonaFideSigning :session="token" theme="auto" :min-height="480" max-height="90vh" @completed="done" /></template> -
在您的服务器上确认结果。 请把浏览器事件仅视为界面信号,并以
envelope.completedWebhook(或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 也会拒绝嵌入式会话来自未获允许的源的调用。