标准集成模式

通过内嵌页面或跳转小程序,快速将云银签核心能力集成到您的业务流程中

对接方式概述

云银签提供了两种主要的集成方式,以适应不同的业务场景和用户角色:

  • 页面内嵌 (Page Embedding): 将云银签的功能页面(如合同发起、管理列表等)通过 <iframe> 直接嵌入到您的系统中。这种方式主要面向您系统的内部用户(如业务员、管理员),提供无缝的操作体验。需要通过 postMessage 机制进行父子页面的通信。
  • 跳转小程序 (Redirect to Mini-Program): 为您的终端用户(如合同签署方、付款方)生成一个特定的 URL 或二维码。用户点击链接或扫码后,系统会自动判断环境(微信/支付宝),并将其引导至对应的云银签小程序完成后续操作(如签署、查看、支付)。完成后,用户可能会被重定向回您指定的页面。

下面将详细介绍几种常用流程的具体对接方案。


准备工作 (必读)

在开始对接后续的具体业务流程(如发起合同、签署合同等)之前,您必须先获取到后续接口调用所需的关键凭证:accessTokenuserId。以下是获取这两个凭证的详细步骤:

核心流程示意图

graph TD; A["第一步:获取应用凭证
(线下向管理员申请)"] --> B(获取 appId 和 appSecret); B --> C["第二步:调用 /service/getAccessToken
(Body 中传入 appId, appSecret)"]; C --> D{获取 accessToken 成功?}; D -- 是 --> E["获得 accessToken 和 corpId"]; D -- 否 --> F["处理错误 (检查 appId/Secret)"]; E --> G["第三步:明确操作者身份
(例如: 业务员张三, 手机号 138...)"]; G --> H["第四步:调用 /member/infoByCorpId
(Header: appId, accessToken)
(Body: 查询条件如手机号/姓名)"]; H --> I{查询成员信息成功?}; I -- 是 --> J["获得操作者 userId (例如: 20001)"]; I -- 否 --> K["处理错误 (检查查询条件/权限)"]; J --> L["完成准备!
后续接口调用 Header 需携带:
appId, accessToken, userId"]; %% 点击事件定义 click C "../api-docs/token/service-token.html#getAccessToken" "查看 获取服务凭证 API 文档" click H "../api-docs/member/member.html#getMemberInfo" "查看 查询企业成员信息 API 文档" %% 样式 style E fill:#d4edda,stroke:#155724,stroke-width:2px style J fill:#d4edda,stroke:#155724,stroke-width:2px style L fill:#cce5ff,stroke:#004085,stroke-width:2px style F fill:#f8d7da,stroke:#721c24,stroke-width:1px style K fill:#f8d7da,stroke:#721c24,stroke-width:1px

步骤详解

第 1 步:获取应用凭证 (appId & appSecret)

  • 在正式对接前,您的企业需要在云银签平台进行注册和认证。
  • 认证通过后,平台管理员会为您分配一对唯一的应用凭证:appIdappSecret
  • 这两个值是后续所有 API 调用的基础,请务必妥善保管,不要泄露。
  • 如何获取: 请联系贵公司的云银签平台管理员。

第 2 步:调用 API 获取访问令牌 (accessToken)

  • 使用您获取到的 `appId` 和 `appSecret`,调用 获取服务凭证 API (`/service/getAccessToken`)。
  • 这是一个 POST 请求,需要将 `appId` 和 `appSecret` 放在请求体 (Request Body) 中。
  • 请求 Body 示例 (JSON):
    {
      "appId": "您从管理员获取的 appId",
      "appSecret": "您从管理员获取的 appSecret"
    }
  • 成功响应 Body 示例 (JSON):
    {
      "code": "200",
      "msg": "成功",
      "data": {
        "accessToken": "生成的访问令牌字符串 (例如: 7eb5d4a7-...) ",
        "corpId": 10001, // 您企业在云银签的 ID
        "expiresIn": 1718888888000 // 令牌过期时间戳 (毫秒)
      }
    }
  • 您需要从响应的 `data` 中提取并保存 accessToken。请注意 expiresIn,令牌会在指定时间后失效,需要重新获取。

第 3 步:理解并获取操作者用户 ID (userId)

  • userId 代表了**在您的系统中实际执行操作的用户**。例如,如果是租房 App,发起租房合同的可能是某个房产中介(张三)。这个"张三"需要在云银签系统中被添加为贵企业(租房 App 公司)的成员,并获得一个唯一的 `userId`。
  • 如何添加成员? 通常由企业管理员在云银签管理后台操作,或者通过调用人员管理相关 API 添加。
  • 在进行具体操作(如发起合同)前,您需要知道是**哪个 `userId`** 在执行这个操作。
  • 您可以通过调用 查询企业成员信息 API (`/member/infoByCorpId`) 来查找特定用户的 `userId`。
  • **【关键】调用此 API 时:**
    • 必须在请求的 **Header** 中携带 appId 和上一步获取的 accessToken
    • 可以在请求 Body 中传入查询条件,例如用户的手机号或姓名,来精确查找。
  • 请求 Header 示例:
    appId: 您企业的 appId
    accessToken: 您获取到的 accessToken
  • 请求 Body 示例 (查询手机号为 138... 的用户):
    {
      "mobile": "13800138000"
    }
  • 成功响应 Body 示例 (JSON):
    {
      "code": "200",
      "msg": "成功",
      "data": [ // 可能返回多个,如果查询条件不唯一
        {
          "userId": 20001, // 这就是您需要的操作者 userId
          "userName": "张三",
          "mobile": "13800138000",
          "userStatus": 0, // 0:有效
          "realName": "张三",
          "realNameStatus": 1 // 1:已实名
        }
        // ... 其他可能匹配的用户 ...
      ]
    }
  • 从返回的 `data` 数组中找到您需要的用户,并获取其 userId

第 4 步:后续接口调用

  • 在完成以上步骤,成功获取到有效的 accessToken 和具体操作者的 userId 后,您就可以调用其他业务接口了(如发起合同、查询合同等)。
  • 【非常重要】 调用后续所有需要授权的业务接口时,**必须** 在请求的 **Header** 中统一携带以下三个参数:
    • appId
    • accessToken
    • userId (当前操作者的 ID)
  • 后续请求 Header 示例:
    appId: 您企业的 appId
    accessToken: 您获取到的 accessToken
    userId: 20001

普通发起合同 (页面内嵌)

此方案适用于需要由您系统的内部用户(如业务员)直接上传文件、填写参与方并发起非模板化合同的场景。发起页面将通过 iframe 嵌入到您的系统中。

前提: 请确保您已完成 准备工作 中的步骤,获取了有效的 accessToken 和当前操作用户的 userId

流程示意图

graph TD; subgraph DevSystemFE ["开发者系统前端"] A[用户点击 发起合同 按钮] --> B[构建内嵌页面 URL]; B -- 携带 accessToken, userId, source --> C["嵌入 iframe (显示 initiat.png)"]; D[监听来自 iframe 的 postMessage]; G --> D; D --> H{收到成功/失败/取消消息?}; H -- 成功 --> I["处理成功逻辑 (提示/跳转)"]; H -- 其他 --> J[处理失败/取消逻辑]; end subgraph 云银签Iframe ["云银签内嵌页面iframe"] C --> E["用户操作 (上传/添加/填写/发起)"]; E --> F(操作完成/取消); F --> G(通过 postMessage 通知父页面); end %% Restored click definitions click B "#direct-initiation-embed-step1" "查看构建URL步骤" click C "#direct-initiation-embed-step2" "查看嵌入iframe步骤" click D "#direct-initiation-embed-step3" "查看监听消息步骤" click G "#direct-initiation-embed-step3" "查看监听消息步骤" %% Testing style definitions one by one - RESTORED style B fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style C fill:#fffbe6,stroke:#faad14,stroke-width:2px,color:#333 style D fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style G fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333

对接方式

页面内嵌 (<iframe>)

步骤详解

第 1 步 (原第 2 步):构建内嵌页面的 URL

  • 基础 URL: https://open.yunyinsign.com/h5/pages/uploadInitiation/index
  • 需要拼接的参数 (Query String):
    • appId: (必填) 准备工作中获取的appId。
    • accessToken: (必填) 准备工作中获取的有效访问令牌。
    • userId: (必填) 准备工作中获取并映射好的当前操作用户的云银签 `userId`。
  • URL 示例:
    https://open.yunyinsign.com/h5/pages/uploadInitiation/index?accessToken=your_unique_access_token_string&userId=20001&source=mySystem

第 2 步 (原第 3 步):在您的页面中嵌入 iframe

  • 在您系统需要发起合同的页面上,使用 HTML 的 <iframe> 标签,将 src 属性设置为上一步构建的 URL。
  • 嵌入后,用户将看到类似下图的云银签发起合同页面,其中第一个签署方(通常是发起人)信息可能会根据传入的 `userId` 自动填充:
  • 普通发起合同页面截图

    截图示例: 普通发起合同

  • 示例代码:
    <iframe
      id="yyq-initiate-iframe"
      src="构建好的URL放在这里"
      width="100%"
      height="800px" /* 根据需要调整高度 */
      frameborder="0">
    </iframe>

第 3 步 (原第 4 步):监听内嵌页面的消息 (postMessage)

  • 内嵌页面在用户完成操作(如发起成功、取消、失败)时,会通过 window.parent.postMessage() 向您的父页面发送消息。
  • 您需要在父页面添加事件监听器来接收这些消息,并根据消息内容进行后续处理。
  • 示例 JavaScript 代码和消息体结构可参考本文档其他内嵌流程的说明,或根据云银签提供的具体规范进行调整(例如,消息 `type` 可能为 `yyq.initiate.direct.result`)。
  • 成功消息通常会包含新创建的合同流程 ID (`signFlowId`)。

注意事项

  • 内嵌页面的具体 URL 需要由云银签提供或在相关文档中查找。
  • 请确保内嵌页面的域名已被添加到浏览器的可信来源中,以便 postMessage 正常工作。
  • accessToken 的有效期需要关注,如果过期,内嵌页面可能无法加载或操作失败。

模板发起合同 (页面内嵌)

前提: 请确保您已完成 准备工作 中的步骤,获取了有效的 accessToken 和当前操作用户的 userId

此方案适用于需要由内部用户(如业务员)先从系统中选择一个已创建好的合同模板,然后通过内嵌的云银签页面填写模板变量并发起合同的场景。

核心流程概览

在用户选择模板并发起之前,您的系统可能需要先管理这些模板。云银签提供了完整的模板管理 API,包括:

您可以根据需要调用这些 API 来维护您系统中的模板库。以下流程图展示了从选择模板到通过内嵌页面发起合同的交互过程:

graph TD; subgraph "开发者系统(后台/前端)" A["准备/管理模板
(增/改/查/启停用等)"] --> B("调用 API: /template/list"); B --> C{"获取模板列表成功?"}; C -- 是 --> D["前端展示模板列表
(见截图: 模板列表)"]; C -- 否 --> E["处理错误"]; D --> F("用户选择模板"); F --> G["构建内嵌页面 URL
(含 templateId, token 等)"]; G --> H["嵌入 iframe 显示发起页面
(见截图: 模板发起)"]; I["监听来自 iframe 的 postMessage"]; end subgraph "云银签内嵌页面 (iframe)" H --> J("用户填写信息 & 发起签署"); J --> K("操作完成/取消"); K --> L("通过 postMessage 通知父页面"); end subgraph "开发者系统(前端)" L --> I; I --> M{"收到成功/失败/取消消息?"}; M -- 成功 --> N["处理成功逻辑
(如:提示发起成功, 刷新状态)"]; M -- 其他 --> O["处理失败/取消逻辑"]; end %% 点击事件定义 click A "../api-docs/template/template.html" "查看模板管理API" click B "../api-docs/template/template.html#templateList" "查看模板列表API" click G "#template-initiation-embed-step2" "查看构建URL步骤" click H "#template-initiation-embed-step3" "查看嵌入iframe步骤" click I "#template-initiation-embed-step4" "查看监听消息步骤" click L "#template-initiation-embed-step4" "查看监听消息步骤" %% 添加样式突出显示可点击节点 %% style A fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style B fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style G fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style H fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style I fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style L fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333

对接方式

页面内嵌 (<iframe>)

步骤详解

第 1 步:(准备) 获取模板列表并在您的系统中展示

  • 您的后端服务调用 模板列表查询 API (`/template/list`) 获取当前企业可用(通常是已启用)的模板列表。
  • 您的前端页面根据 API 返回的数据,渲染一个模板选择界面,如下图所示:
  • 模板列表截图

    截图: 模板列表

  • 用户在此界面选择一个想要使用的模板。您需要获取用户选择的模板 `templateId`。
  • 确保已获取有效的 `accessToken` (参见 获取服务凭证 API)。
  • 需要准备发起人对应的和 `userId`。

第 2 步:构建内嵌页面的 URL

  • 基础 URL: `https://open.yunyinsign.com/h5/pages/home/InitiateContract/components/detail`
  • 需要拼接的参数 (Query String):
    • `appId`: (必填) 基础应用ID。
    • `accessToken`: (必填) 获取到的访问令牌。
    • `userId`: (必填) 发起人用户 ID。
    • `templateId`: (必填) 用户在第 1 步选择的模板 ID。
  • URL 示例:
    https://open.yunyinsign.com/h5/pages/home/InitiateContract/components/detail?accessToken=YOUR_TOKEN&userId=20001&templateId=TPL001&source=mySystem

第 3 步:在您的页面中嵌入 iframe

  • 使用 HTML 的 <iframe> 标签,将 src 属性设置为上一步构建的 URL。
  • 嵌入后,用户将看到类似下图的云银签模板发起页面:
  • 模板发起页面截图

    截图: 模板发起

  • 示例代码:
    <iframe id="yyq-template-initiate-iframe" src="构建好的URL放在这里" width="100%" height="800px" frameborder="0"></iframe>

第 4 步:监听内嵌页面的消息 (postMessage)

  • 内嵌页面在用户完成操作(如发起成功、取消)时,会通过 `window.parent.postMessage()` 向您的父页面发送消息。
  • 您需要在父页面添加事件监听器来接收这些消息,并根据消息内容(如 `status`, `data.signFlowId`, `error`)进行后续处理。
  • 示例 JavaScript 代码和消息体结构,请参考 普通发起合同 (内嵌) 流程的第 4 步说明(消息类型 `type` 可能为 `yyq.initiate.template.result`,具体请与后端确认)。

注意事项

  • 如果模板包含需要预填的组件(如发起人信息),可以在构建 URL 时将这些信息作为参数传递给内嵌页面,以减少用户手动输入(具体参数需确认)。
  • `accessToken` 的有效期需要关注,如果过期,内嵌页面可能无法加载或操作失败。

发起方签署/填写 (页面内嵌)

前提:

  • 合同已通过 普通发起模板发起 流程创建。
  • 请确保您已完成 准备工作 中的步骤,获取了有效的 accessToken 和当前登录系统的操作用户(即发起方成员)的 userId
  • 您需要知道当前操作用户所属的企业的 openCorpId

此方案适用于合同发起后,需要由发起方(您系统的内部用户)在您的系统内继续完成查看、填写或签署合同信息的场景。

核心流程示意图

graph TD; subgraph "发起方处理流程" A["用户登录系统 (发起方员工)"] --> B["调用 API 获取企业合同列表
(/signTask/enterpriseContracts/list)
Header: appId, accessToken, userId (操作人), openCorpId (企业ID)"]; B --> C{获取列表成功?
获取 flowId, operateStatus, directFlag 等}; C -- 是 --> D["前端根据 operateStatus
展示合同列表及对应操作按钮
(如: 查看, 去填写, 去签署)"]; C -- 否 --> E["处理错误"]; D --> F["用户点击操作按钮"]; F --> G["获取合同 flowId 及其他必要信息"]; G --> H["根据 operateStatus 和 directFlag
构建特定的H5内嵌页面 URL"]; H --> I["嵌入 iframe 显示H5处理页面
(查看/填写/签署页)"]; I --> K("用户完成操作"); K --> L("操作完成/取消"); L --> M("通过 postMessage 通知父页面"); M --> J["监听来自 iframe 的 postMessage"]; J --> N{"收到成功/失败/取消消息?"}; N -- 成功 --> O["处理成功逻辑 (如:刷新列表, 提示成功)"]; N -- 其他 --> P["处理失败/取消逻辑"]; end click B "../api-docs/signtask/query.html#getEnterpriseContractList" "查看企业合同列表API" click D "showImage:my-contact.png" "点击查看截图: 我的合同 (示意图)" click H "#initiator-action-embed-step2" "查看构建URL步骤" click I "#initiator-action-embed-step3" "查看嵌入iframe步骤" click J "#initiator-action-embed-step4" "查看监听消息步骤" click M "#initiator-action-embed-step4" "查看监听消息步骤" style B fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style H fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style I fill:#fffbe6,stroke:#faad14,stroke-width:2px,color:#333 style J fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style D fill:#fffbe6,stroke:#faad14,stroke-width:2px,color:#333 style M fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333

对接方式

页面内嵌 (<iframe>),内嵌页面为H5页面。

步骤详解

第 1 步:获取并展示企业合同列表及操作状态

  • 当发起方用户登录您的系统后,您的后端服务需要调用 企业合同列表 API (`/signTask/enterpriseContracts/list`)。
  • **重要:** 调用此 API 时,必须在 **Header** 中传入:
    • appId: 您的应用ID。
    • accessToken: 当前登录用户的有效访问令牌。
    • userId: 当前登录用户的 `userId`。
    • openCorpId: 当前登录用户所属企业的ID。
  • API 会返回该企业相关的合同列表。对于每份合同,您需要关注以下关键字段(通常在返回的 `data` 数组的每个对象中):
    • flowId: 合同流程ID。
    • flowStatus: 整体流程状态。
    • operateStatus: 当前用户(即Header中传入的`userId`)对该合同的操作状态。例如:1-填写, 2-签署, 4-查看等。这是判断应显示何种操作按钮的关键。
    • directFlag: 是否直发(0-否, 1-是)。当 `operateStatus` 为签署时,此字段用于区分使用哪个签署页面。
    • 其他合同基本信息如 flowTitle(合同标题)等。
  • 您的前端页面根据返回的数据,渲染一个合同列表。针对列表中的每一份合同,根据其 operateStatus,为当前用户显示相应的操作按钮。例如:
    • 如果 operateStatus 指示"待查看",则显示"查看合同"按钮。
    • 如果 operateStatus 指示"待填写",则显示"去填写"按钮。
    • 如果 operateStatus 指示"待签署",则显示"去签署"按钮。
    参考截图: 我的合同列表截图

    截图示意: 合同列表 (按钮根据状态动态生成)

第 2 步:根据操作类型构建特定的H5内嵌页面 URL

  • 当用户点击具体的操作按钮(如"查看合同"、"去填写"、"去签署")时,您已经获取了该合同的 flowId 以及相关的 operateStatusdirectFlag
  • 您需要根据这些信息,选择并构建以下四种H5内嵌页面的URL之一。所有H5内嵌页面都需要以下通用参数,请通过Query String传递:
    • appId: (必填) 您的应用ID。
    • accessToken: (必填) 当前登录用户的有效访问令牌。
    • userId: (必填) 当前登录用户的 `userId`。
    • flowId: (必填) 当前操作的合同流程ID。
  • URL构建逻辑:
    1. 如果操作是"查看合同" (假设 operateStatus 对应查看):
      • 基础 URL: https://open.yunyinsign.com/h5/pages/myActivities/lookOver/
      • 示例 URL: https://open.yunyinsign.com/h5/pages/myActivities/lookOver/?appId=YOUR_APPID&accessToken=YOUR_TOKEN&userId=USER_ID&flowId=FLOW_ID
    2. 如果操作是"去填写" (假设 operateStatus 对应填写):
      • 基础 URL: https://open.yunyinsign.com/h5/pages/myActivities/signingPage (此页面用于填写)
      • 示例 URL: https://open.yunyinsign.com/h5/pages/myActivities/signingPage?appId=YOUR_APPID&accessToken=YOUR_TOKEN&userId=USER_ID&flowId=FLOW_ID
    3. 如果操作是"去签署" (假设 operateStatus 对应签署):
      • 此时需要判断 directFlag:
        • 如果 directFlag1 (直发):
          • 基础 URL: https://open.yunyinsign.com/h5/pages/myActivities/directInitiation
          • 示例 URL: https://open.yunyinsign.com/h5/pages/myActivities/directInitiation?appId=YOUR_APPID&accessToken=YOUR_TOKEN&userId=USER_ID&flowId=FLOW_ID
        • 如果 directFlag0 (非直发):
          • 基础 URL: https://open.yunyinsign.com/h5/pages/myActivities/fillout
          • 示例 URL: https://open.yunyinsign.com/h5/pages/myActivities/fillout?appId=YOUR_APPID&accessToken=YOUR_TOKEN&userId=USER_ID&flowId=FLOW_ID

第 3 步:在您的页面中嵌入 iframe (加载H5页面)

  • 使用 HTML 的 <iframe> 标签,将 src 属性设置为上一步根据逻辑构建好的特定H5页面 URL。
  • 用户将在iframe中看到对应的云银签H5页面(查看、填写或特定类型的签署页面)。
  • 以下是填写和签署页面的H5界面截图示例:
  • H5合同填写页面截图
    示例:H5合同填写页面
    (对应 .../signingPage)
    H5合同签署页面截图
    示例:H5合同签署页面
    (对应 .../fillout 或 .../directInitiation)
  • 示例代码:
    <iframe id="yyq-h5-task-iframe" src="构建好的特定H5页面URL放在这里" width="100%" height="800px" frameborder="0"></iframe>

第 4 步:监听内嵌H5页面的消息 (postMessage)

  • 内嵌的H5页面在用户完成操作(查看完毕可能无消息,填写/签署成功、取消等)时,会通过 window.parent.postMessage() 向您的父页面发送消息。
  • 您需要在父页面添加事件监听器来接收这些消息。请参考 可内嵌页面参考 章节中关于 H5 端 `postMessage` 的详细说明,特别是监听 event.data.type 可能的值,如:
    • goBack: 返回上一层页面。
    • contract: 返回合同列表页。
    • goShare: 返回分享页面。
    • message: 一般性消息,常用于报错提示 (例如:Token过期,具体消息在 event.data.message)。
  • 根据接收到的消息类型和内容,进行相应的处理,例如关闭iframe、刷新合同列表、给出用户提示等。

注意事项

  • 请务必使用正确的 operateStatus 值来判断应展示的操作和构建的URL。该状态值的具体含义请参照 `/signTask/enterpriseContracts/list` 接口的文档。
  • 所有H5内嵌页面的基础域名请以云银签实际提供为准。
  • 确保在调用企业合同列表 API 和构建内嵌 URL 时,使用的 `accessToken` 和 `userId` 是**当前登录的发起方员工**的凭证,且`openCorpId`是其所属企业。
  • 关注 `accessToken` 的有效期。
  • 重要提示:发起方完成操作后,根据企业配置,合同可能进入"待审批"状态,需要等待内部审批人处理后才能流转至下一方。请参考 合同审批 (API 对接) 章节。

合同审批 (API 对接)

适用场景: 对于需要内部审核流程的企业,例如确保合同内容合规、控制重要印章(如公章)的使用权限等,可以在合同流转过程中加入此审批环节。

流程位置: 通常发生在合同发起方完成其签署/填写操作之后,在合同流向其他外部签署方或支付方之前。

实现方式: 此功能**完全通过 API 对接**,需要在开发者自己的业务系统(例如租房 App 的管理后台)中为具有审批权限的用户(如管理员、法人)构建审批管理界面。

前提:

  • 审批人已在云银签系统中注册并完成实名认证(设置了签署密码)。
  • 审批流程已在云银签平台或通过 API 配置(具体配置方式请参考相关文档或联系技术支持)。
  • 您已完成 准备工作,能获取到有效的 accessToken 以及**审批人**的 userId

核心流程示意图 (开发者系统内实现)

graph TD; subgraph ClientSystem ["开发者系统 (审批管理界面)"] A[审批人登录系统] --> B["调用 API 获取 待审批列表
(/signTask/getApprovalList, docQueryType=0)
Header: appId, accessToken, 审批人userId"]; B --> C{获取列表成功?}; C -- 是 --> D["展示待审批合同列表
(需显示合同名称, 发起人, 审批ID等)"]; C -- 否 --> E[处理错误]; D --> F["审批人选择合同 (获取 approvalId)"]; F --> G{选择操作: 通过/驳回}; G -- 通过 --> H["调用'审批通过' API
(/signTask/approvalSign, status=2)
Header: appId, accessToken, 审批人userId
Body: approvalId, approvalStatus=2
可能需验证审批人签署密码"]; G -- 驳回 --> I["调用'审批驳回' API
(/signTask/approvalCancel, status=3)
Header: appId, accessToken, 审批人userId
Body: approvalId, approvalStatus=3, failReason"]; H --> J{审批API调用成功?}; I --> J; J -- 是 --> K[系统内更新合同状态, 通知相关方]; J -- 否 --> L[处理API错误]; end subgraph NextSteps ["后续流程"] M["审批通过: 合同进入下一环节
(如: 等待外部用户签署/支付)"]; N["审批驳回: 合同流程中止/退回发起人"]; end ClientSystem --> NextSteps; %% API Links (Keep as is) click B "../api-docs/signtask/获取审批管理列表_OpenAPI.json" "查看 获取审批列表 API 文档" click H "../api-docs/signtask/审批合同用章_OpenAPI.json" "查看 审批通过 API 文档" click I "../api-docs/signtask/撤销审批合同用章_OpenAPI.json" "查看 审批驳回 API 文档" %% Styles (Keep as is) style B fill:#e6f7ff,stroke:#096dd9,stroke-width:2px style H fill:#d4edda,stroke:#155724,stroke-width:2px style I fill:#f8d7da,stroke:#721c24,stroke-width:2px style K fill:#cce5ff,stroke:#004085,stroke-width:2px

步骤详解

第 1 步:构建审批人工作台

  • 在您的业务系统中,为指定的审批角色(管理员、法人等)创建一个"审批管理"或"待我审批"的页面。
  • 审批人登录系统后,访问此页面。

第 2 步:调用 API 获取待审批列表

  • 您的后端服务调用 获取审批管理列表 API (`/signTask/getApprovalList`)。
  • **重要:**
    • 请求 **Header** 中必须携带 `appId`, `accessToken` 和 **当前登录审批人的 `userId`**。
    • 请求 **Body** 中设置 `docQueryType` 为 `0` (表示查询"待我审批")。可以根据需要添加其他筛选条件(如发起时间范围、合同名称等)。
  • 请求 Body 示例 (查询待我审批):
    {
      "docQueryType": 0,
      "listPageNo": 1,
      "listPageSize": 10
    }
  • API 会返回该审批人名下待处理的审批任务列表。您需要解析响应数据,特别是获取每条记录的 `approvalId` (审批申请ID) 和相关的合同信息(如 `signFlowName`, `initiatorName`, `createTime` 等)。
  • 成功响应 Body 示例 (部分字段):
    {
      "code": "200",
      "msg": "成功",
      "data": [
        {
          "approvalId": 987654321, // 审批申请ID (非常重要)
          "approvalCode": "APV20240521001",
          "approvalName": "市场部合同用章审批",
          "signFlowId": 123456789,
          "signFlowName": "汽车租赁合同testtt",
          "approvalType": 1, // 1: 合同用章审批
          "approvalStatus": 1, // 1: 审批中 (待当前审批人处理)
          "initiatorName": "梁运和",
          "createTime": "2024-05-21T10:00:00"
          // ... 其他字段 ...
        }
        // ... more approval tasks ...
      ]
    }
  • 在前端页面展示这个列表,并为每条记录提供"通过"和"驳回"的操作按钮。

第 3 步:调用 API 执行审批操作

  • 审批通过:
    • 当审批人点击"通过"时,您的后端调用 审批通过 API (`/signTask/approvalSign`)。
    • 请求 **Header**:`appId`, `accessToken`, **审批人的 `userId`**。
    • 请求 **Body**:必须包含 `approvalId` (从列表获取) 和 `approvalStatus` 设置为 `2`。
    • 请求 Body 示例:
      {
        "approvalId": 987654321,
        "approvalStatus": 2
      }
    • 注意: 此接口**可能**会触发验证审批人的签署密码(取决于系统安全设置),如果验证失败会返回错误。请确保审批人在个人认证时已设置签署密码 (参考 个人认证更新 API)。
  • 审批驳回:
    • 当审批人点击"驳回"时,您的后端调用 审批驳回 API (`/signTask/approvalCancel`)。(注意:API 名字是 `approvalCancel`,但实际用于驳回场景)
    • 请求 **Header**:`appId`, `accessToken`, **审批人的 `userId`**。
    • 请求 **Body**:必须包含 `approvalId` 和 `approvalStatus` 设置为 `3`。建议同时提供 `failReason` (驳回原因) 方便发起人了解情况。
    • 请求 Body 示例:
      {
        "approvalId": 987654321,
        "approvalStatus": 3,
        "failReason": "合同金额与条款不符,请修改后重新提交。"
      }
  • 处理 API 的响应结果,如果成功,则刷新审批列表或更新界面状态。

第 4 步:处理审批结果

  • 审批通过后: 合同会自动流转到下一个需要操作的参与方(例如,外部签署人)。您可以引导这些用户按 合同签署/支付 (跳转小程序) 流程操作。
  • 审批驳回后: 合同流程通常会中止,状态变为"已驳回"。您需要根据业务逻辑决定如何通知发起人(例如,站内信、短信)以及是否允许发起人修改后重新提交审批。

注意事项

  • 审批人的 `userId` 获取方式与普通员工类似,通过 查询企业成员信息 API 获取。
  • 企业可能存在多级审批或会签等复杂流程,此处的 API 主要针对单节点审批场景。如需更复杂的审批流配置,请查阅详细的审批配置文档或联系技术支持。
  • 确保审批人已完成实名认证并设置了签署密码,否则"审批通过"操作可能失败。
  • 【重要】自动跳过审批: 如果合同是由配置好的审批人(例如管理员、法人)本人直接发起的,系统会自动跳过该审批环节,合同将直接流转至下一环节(如等待外部用户签署/支付)。

合同签署/支付 (跳转小程序)

前提:

  • 合同已完成所有前置步骤,包括发起方的操作以及必要的内部审批(如果配置了审批流程,合同状态需为"审批通过"或直接进入签署环节)。
  • 请确保您已完成 准备工作 中的步骤,获取了有效的 accessToken
  • 您需要能获取到目标操作用户(签署人/支付人)的 participantId (通常从合同详情或列表 API 中获取)。

核心流程概览

这个流程通常发生在合同已经对用户可见之后。开发者系统需要先获取用户的合同列表,然后为待处理的合同生成跳转小程序的入口。以下是主要步骤:

graph TD; subgraph "开发者系统 (后台/前端)" AA["合同已发起
(通过内嵌等方式)"] --> A["调用 API 获取
指定用户的合同列表"]; A --> B{"获取列表成功?"}; B -- 是 --> C["前端展示合同列表
(类似 my-contact.png)"]; B -- 否 --> D["处理错误"]; C --> E["用户选择合同
并点击 签署/支付/分享"]; E --> F["调用 API 获取跳转 URL"]; F -- "请求参数: flowId, participantId,
source(wx/alipay), redirectUrl, extParam" --> G{"获取 URL 成功?"}; G -- 是 --> H["生成按钮链接或二维码
(类似 share-contact.png)"]; G -- 否 --> I["处理错误"]; J["在 redirectUrl 页面
监听回调参数"]; end subgraph "终端用户 (App/H5/扫码)" H --> K["点击链接 / 扫描二维码"]; end subgraph "云银签系统 (后端/中间页)" K --> L["接收请求, 判断环境
根据 source 重定向"]; end subgraph "云银签小程序 (微信/支付宝)" L --> M["加载签署/支付任务
(类似 xcx.png)"]; M --> N["用户完成操作"]; N --> O["操作完成/取消/失败"]; O --> P["携带结果参数
跳转回 redirectUrl"]; end subgraph "开发者系统 (前端回调页)" P --> J; J --> Q{"解析回调参数
(status, extParam...)"}; Q --> R["向用户展示结果
建议后端再查询确认状态"]; end %% 点击事件定义 click A "#signing-payment-redirect-step1" "查看获取列表说明" click F "#signing-payment-redirect-step2" "查看获取URL说明" click H "#signing-payment-redirect-step3" "查看提供入口说明" click J "#signing-payment-redirect-step4" "查看处理回调说明" click R "#signing-payment-redirect-step4" "查看处理回调说明" %% 特殊点击定义,用于触发图片弹窗 (使用特殊前缀) click C "showImage:my-contact.png" "点击查看截图: 我的合同" click H "showImage:share-contact.png" "点击查看截图: 分享合同" click M "showImage:xcx.png" "点击查看截图: 小程序签署邀请页" %% 添加样式 style A fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style F fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 style J fill:#e6f7ff,stroke:#096dd9,stroke-width:2px,color:#333 %% 为可查看图片的节点添加不同样式 (例如,不同的边框或图标) style C fill:#fffbe6,stroke:#faad14,stroke-width:2px,color:#333 style H fill:#e6f7ff,stroke:#faad14,stroke-width:2px,color:#333 style M fill:#fffbe6,stroke:#faad14,stroke-width:2px,color:#333

对接方式

跳转小程序 (URL / 二维码)

步骤详解

第 1 步:(准备) 获取用户合同列表

  • 您的系统需要先调用一个 API /contract/listByUserPhone,传入终端用户的手机号,获取该用户相关的合同列表。
  • API 应返回包含合同基本信息(名称、状态等)、流程 ID (`flowId`) 以及每个待处理签署方/支付方的参与者 ID (`participantId`) 的数据。
  • 您的 App 或 H5 页面根据返回的数据,渲染一个合同列表界面供用户查看,类似下图:
  • 我的合同列表截图

    截图示例: 我的合同

第 2 步:(核心) 调用 API 获取跳转 URL

  • 当用户需要对某份合同进行签署或支付时,您的系统需要调用一个 API /signTask/contract/appletForParticipantUrl 来获取跳转到云银签小程序的 URL。
  • 调用此 API 需要传递以下核心参数:
    • participantId: (必填) 具体操作的签署方或支付方的参与者 ID。
    • type: (推荐) 指定目标小程序,传 wxalipay。如果您的入口明确区分微信/支付宝(如不同按钮),请务必传递此参数。若不传,云银签会尝试自动判断或默认微信。
    • redirectUrl: (必填) 用户在小程序完成操作后,云银签将携带结果参数跳转回的目标 H5 页面 URL。**此 URL 必须是公网可访问的,并且需要进行 URL Encode 编码**。
    • extParam: (可选) 开发者自定义的扩展参数,例如订单号、用户标识等。云银签会在回调时原样带回。**此参数也需要进行 URL Encode 编码**。
  • API 成功调用后,会返回一个可以直接使用的跳转 URL。
    微信短链接或支付宝拼接地址,前端直接window.open即可

第 3 步:在您的应用中提供入口 (链接或二维码)

  • **按钮/链接:** 将上一步获取到的 URL 直接设置为操作按钮(如"立即签署"、"去支付"、"分享签署链接")的点击跳转目标。
  • **二维码:** 如果需要提供扫码入口(例如分享给他人签署),使用您系统熟悉的前端或后端二维码生成库,将上一步获取到的 URL 生成二维码图片展示给用户。类似下图:
  • 分享合同二维码截图

    截图示例: 分享合同

第 4 步:处理回调 (在您的 redirectUrl 页面)

  • 用户点击链接或扫码后,会被引导至云银签小程序完成操作。完成后,小程序会跳转回您在第 2 步提供的 redirectUrl
  • 跳转时,云银签会在 URL Query String 中附加结果参数。您需要在 redirectUrl 对应的 H5 页面中,使用 JavaScript 解析这些参数。
  • 关键回调参数示例 (具体参数名需与后端确认):
    // 成功示例 (签署+支付)
    https://yourapp.com/callback?flowId=FLOW789&participantId=PART123&status=success&signStatus=signed&payStatus=paid&orderNo=PAYORDER001&extParam=YOUR_ENCODED_PARAM
    
    // 仅签署成功示例
    https://yourapp.com/callback?flowId=FLOW789&participantId=PART123&status=success&signStatus=signed&extParam=YOUR_ENCODED_PARAM
    
    // 用户取消示例
    https://yourapp.com/callback?flowId=FLOW789&participantId=PART123&status=cancel&extParam=YOUR_ENCODED_PARAM
    
    // 失败示例
    https://yourapp.com/callback?flowId=FLOW789&participantId=PART123&status=fail&errorCode=SIGN_FAIL&errorMessage=签名验证失败&extParam=YOUR_ENCODED_PARAM
  • 您的回调页面需要:
    1. 解析 URL 获取 status, signStatus, payStatus, errorCode, extParam (解码后使用) 等参数。
    2. 根据参数向用户展示清晰的操作结果(成功、失败原因、取消等)。
    3. **【重要建议】** 前端收到的回调仅用于即时展示。为确保数据最终一致性,您的**后端服务应该根据收到的 `flowId` (或从 `extParam` 解码出的业务单号),再次调用云银签的合同状态查询 API,获取最准确、最权威的合同状态,并更新您自己系统的业务状态。**
  • 用户进入小程序后看到的界面可能类似下图,后续流程由云银签小程序引导:
  • 小程序签署邀请页面截图

    截图示例: 小程序签署邀请页

注意事项

  • `redirectUrl` 和 `extParam` 在传入获取跳转 URL 的 API 时,**必须进行 URL Encode 编码**。
  • `redirectUrl` 必须是公网可访问的 H5 页面地址。
  • 请务必做好前端回调参数的解析和后端状态的最终确认。

可内嵌页面参考

本章节详细列出了云银签系统提供的、可内嵌至您自有系统中的PC端和H5端页面,包括所需的跳转参数及与内嵌页面通信的方式。请注意,所有内嵌页面的域名均以 https://open.yunyinsign.com为准。

PC 端可内嵌页面

以下是PC端可以内嵌的页面及其说明。请确保您已参照 准备工作 获取了必要的 appIdtoken (即 accessToken)。

1. 目录结构 (可内嵌页面URL)

  • http://open.yunyinsign.com/#/personalCertificate - 个人认证页面
  • http://open.yunyinsign.com/#/companyCertification - 企业认证第一步页面 (企业认证只需要接入第一步的页面)
  • http://open.yunyinsign.com/#/companyCertificationTwo - 企业认证第二步页面
  • http://open.yunyinsign.com/#/editTemplates - 新增模板 (组件操作页面从新增过去的不需要单独接入)
  • http://open.yunyinsign.com/#/settingTemplate - 控件操作
  • http://open.yunyinsign.com/#/designatedSignature - 直接发起指定签署位置 (控件操作)
  • http://open.yunyinsign.com/#/signingPage - 合同填写页面
  • http://open.yunyinsign.com/#/fillout - 合同签署盖章页面 (和直接发起指定签署位置的页面)
  • http://open.yunyinsign.com/#/directInitiation - 直接发起不指定位置的合同盖章页面
  • http://open.yunyinsign.com/#/lookOver - 合同查看页面
  • http://open.yunyinsign.com/#/controlStamping - 印章列表 (个人和公司)
  • http://open.yunyinsign.com/#/personalSeal - 新增印章 (个人)
  • http://open.yunyinsign.com/#/corporate - 新增印章 (公司印章)
  • http://open.yunyinsign.com/#/sealDetail - 印章详情和授权 (公司印章)

2. 页面跳转参数详情

注意:参数名 token 在此上下文中通常指代 accessToken

2.1 个人认证页面 (personalCertificate)
参数名是否必传参数说明
appId应用ID
token登录标识 (accessToken)
userId用户需要绑定的用户ID
2.2 企业认证第一步页面 (companyCertification)
参数名是否必传参数说明
appId应用ID
token登录标识 (accessToken)
userId用户需要绑定的用户ID
corpId企业ID
corpName企业名称
2.3 新增/编辑模板页面 (editTemplates)
参数名是否必传参数说明id参数说明
appId应用ID根据templateType决定:
0: 新增模版 - 不用传
1: 设置模版 - 必须传
2: 使用模版 - 必须传
3: 直接发起 - 不用传
token登录标识 (accessToken)
userId用户需要绑定的用户ID
corpId企业ID
templateType0: 新增模版 | 1: 设置模版 | 2: 使用模版 | 3: 直接发起
id见右侧模板ID
2.4 合同处理系列页面 (signingPage, fillout, directInitiation, lookOver)
参数名是否必传参数说明
appId应用ID
token登录标识 (accessToken)
userId用户需要绑定的用户ID
corpId企业ID
id合同ID (对应您其他文档中的 flowId)

3. 与PC内嵌页面通信 (postMessage)

父页面可以通过以下方式监听来自PC内嵌iframe的消息:

window.addEventListener('message', (e) => {
    if (e.origin !== 'https://open.yunyinsign.com') { // 校验来源, open.yunyinsign.com 替换为实际域名
        // return; // 生产环境建议开启来源校验
    }
    console.log('iframe数据', e.data); // e.data 通常是一个对象
    if (e.data && typeof e.data === 'object' && e.data.type) {
        console.log('事件类型:', e.data.type);
        // 根据 e.data.type 处理不同事件
        // 例如: if (e.data.type === 'goBack')
        //       if (e.data.type === 'succeed')
    }
});

PC内嵌页面可能抛出的 e.data.type 值及其说明:

接受值的参数名 (e.data.type)参数说明
goBack返回上一层的标识
succeed事件执行成功的返回