QI Sign 手册
QI Tech 的 webhooks 不应被严格映射。 返回的 webhooks payload 中可能会新增额外字段。
简介
欢迎使用 QiTech 签名 API!此 API 提供电子文件签名服务!
遇到问题?
如有任何问题,请联系我们的支持团队(suporte@qitech.com.br),我们将尽快回复。
环境
我们为客户提供两个环境。API 的基础 URL 为:
- 生产环境 -
https://api.sign.qitech.com.br/ - 沙盒环境 -
https://api.sandbox.sign.qitech.com.br/
不得在 QI Tech 的沙盒环境中使用真实个人和/或法人数据。
仅限 HTTPS
出于安全考虑,与 QI Tech API 的所有通信必须使用 HTTPS。为避免因疏忽或其他原因发起 HTTP 调用,本服务器仅开放端口 443 并使用 TLS 1.2 通信。使用其他协议的调用将被自动拒绝。
认证
要认证调用,请使用以下代码:
# No shell, você somente precisa adicionar o header adequado em cada requisição
curl "api_endpoint_here"
-H "Authorization: EXAMPLE_API_KEY"
将 API Key 'EXAMPLE_API_KEY' 替换为从我们支持获取的密钥。
我们使用 API Key 来授权访问 API。它可能已通过电子邮件发送给您。如果您还未收到密钥,请发送邮件至 suporte@qitech.com.br。
我们的 API 要求在所有向服务器发送的请求中,通过如下 header 传递 API Key:
Authorization: EXAMPLE_API_KEY
信封(Envelope)是包含待电子签名文件的对象。它们由一个或多个文件创建,可通过电子邮件、SMS 或 WhatsApp 发送以供签署。要创建信封,您需要向 API 发送一个或一组文件。信封将被创建,您将收到其唯一标识符。
创建信封
要创建信封,请向端点 /sign/envelope 发送 POST 请求,并附上签署人数据。
curl -X POST \
https://api.sign.qitech.com.br/sign/envelope \
-H 'Content-Type: application/json' \
-H "Authorization: EXAMPLE_API_KEY" \
-d '{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"subject": "CCB QiTech",
"expiration_date": "2023-09-20",
"signers": [
{
"id": "1",
"name": "John Sample",
"email": "johnsample@test.com",
"birthdate": "1992-09-15",
"document_number": "111.111.111-11",
"phone": {
"international_dial_code": "55",
"area_code": "11",
"number": "988878722"
},
"document_submission_method": "email",
"authentication_submission_method": "sms"
}
]
}'
Envelope 对象定义
信封的所有信息交换均使用以下对象定义。在某些情况下,为便于实现并减少各方之间的数据流,部分信息可能会被省略。
| 名称 | 类型 | 描述 |
|---|---|---|
| id | string | 信封的唯一标识符。 此编号必须是唯一的 |
| subject | string | 信封标题。显示在电子邮件主题中。 |
| expiration_date | string | 信封过期日期,格式为 YYYY-MM-DD。 |
| signers | list | 描述信封签署人的 Signer 类型对象列表。 |
Signer 对象定义
| 名称 | 类型 | 描述 |
|---|---|---|
| id | string | 签署人的交易标识符。 此编号在每个信封中必须是唯一的 |
| string | 签署人的电子邮件地址。 | |
| name | string | 签署人全名。 |
| birthdate | string | 签署人出生日期,格式为 YYYY-MM-DD。 |
| document_number | string | 签署人的文件号码。 |
| phone | object | 描述签署人电话的对象。 |
| phone.international_dial_code | string | 签署人电话的国家代码。 |
| phone.area_code | string | 签署人电话的 区号。 |
| phone.number | string | 签署人的电话号码。 |
| document_submission_method | enum | 发送文件供签署的方式。 可用方式:email、sms 和 whatsapp |
| authentication_submission_method | enum | 发送签署认证令牌的方式。 可用方式:email、sms 和 whatsapp |
- email 和 phone 字段可一起或单独发送,但至少需要发送其中一个。
- 所有字段均为必填。
信封创建响应
信封创建成功后,响应将是一个包含信封 id 和状态的 JSON,示例如下:
响应示例
{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"status": "created"
}
向签署人添加身份证件
要向签署人添加身份证件,请为每个要添加的文件向端点 /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document 发送 POST 请求。文件必须按以下格式在请求正文中发送:
{
"document_b64": "Q5YACgAAAABDlgAbAAAAAEOWAC0AAAAAQ5YAPwAAAABDlgdN...",
"template": "cnh_front",
"file_type": "jpeg"
}
可用模板
对于每种身份证件类型,需要提供相应的模板。可用模板为:
| 模板 | 描述 |
|---|---|
| cnh_front | 巴西国家驾驶证正面(照片面)。 |
| cnh_back | 巴西国家驾驶证背面(签名面)。 |
| rg_front | 巴西身份证正面(照片面)。 |
| rg_back | 巴西身份证背面(数据面)。 |
发送属性说明
| 属性 | 描述 |
|---|---|
| document_b64 | 以 base64 编码的身份证件。 |
| template | 声明用于图像分析的模板。 |
| file_type | 标识发送文件的格式,jpeg。若未发送,则默认值为 jpeg。 |
- 身份证件的最大大小为 10 MB
- 除
file_type外,所有字段均为必填。
添加身份证件的响应
身份证件添加成功后,响应将是一个包含 created_at 的 JSON,示例如下:
响应示例
{
"created_at": "2023-01-01T00:00:00.000Z"
}
身份证件 采集
如果未上传签署人的身份证件,将在签署时要求签署人进行采集。
向信封添加文件
要向信封添加待签署文件,请为每个要添加的文件向端点 /sign/envelope/\{envelope_id\}/document 发送 POST 请求。文件必须按以下格式在请求正文中发送:
{
"id": "3dfc5526-ee47-4b63-ad97-ddaf5b1c9110",
"document_b64": "Q5YACgAAAABDlgAbAAAAAEOWAC0AAAAAQ5YAPwAAAABDlgdN...",
"name": "Laudo de vistoria de entrada",
"document_type": "pdf"
}
- 文件的最大大小为 10 MB
Document 对象定义
| 名称 | 类型 | 描述 |
|---|---|---|
| id | string | 文件标识符。 此编号在信封中必须是唯一的 可选 若未提供,我们将生成一个 36 个字符的 UUID4 格式的 GUID。 |
| document_b64 | string | 以 base64 编码的文件。 |
| name | string | 文件名 称。 |
| document_type | enum | 文件类型。 可用类型:pdf |
向信封添加文件的响应
向信封添加文件成功后,响应将是一个包含文件标识符和创建日期的 JSON,示例如下:
响应示例
{
"id": "3dfc5526-ee47-4b63-ad97-ddaf5b1c9110",
"created_at": "2023-01-01T00:00:00.000Z"
}
发送信封以供签署
要发送信封以供签署,请向端点 /sign/envelope/\{envelope_id\} 发送 PATCH 请求
curl -X PATCH \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY" \
-d '{
"status": "submitted"
}'
发送信封以供签署的响应
信封发送成功后,响应将是一个包含信封状态的 JSON,示例如下:
响应示例
{
"status": "submitted"
}
信封发送签署后,签署人将收到含有文件签署链接的电子邮件或短信。
访问链接后,签署人需填写 CPF,签署文件并根据合作伙伴的流程完成人脸和/或文件验证。签署完成后,签署人将被重定向至成功页面。
查询信封数据
要查看信封数据(如状态和签署人信息),请向端点 /sign/envelope/\{envelope_id\} 发送 GET 请求
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY"
如果请求成功,响应将是一个包含信封状态和签署人信息的 JSON,示例如下:
响应示例
{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"subject": "Laudo de vistoria de entrada",
"expiration_date": "2023-09-20T02:59:59Z",
"status": "completed",
"signers": [
{
"id": "1",
"name": "John Sample",
"email": "johnsample@test.com",
"birthdate": "1992-09-15",
"document_number": "111.111.111-11",
"phone": {
"international_dial_code": "55",
"area_code": "11",
"number": "988878722"
},
"document_submission_method": "email",
"authentication_submission_method": "email",
"status": "signed",
"signed_at": "2023-03-21T15:30:00.000Z",
"signature_url": "https://sign.qitech.com.br/s/s2S33dD",
"documents": [
{
"id": "8d3c3f1a-1a1a-1a1a-1a1a-1a1a1a1a1a1a",
"name": "Laudo de vistoria de entrada",
"document_type": "pdf"
}
]
}
]
}
- 信封状态可以是
created、submitted、completed、canceled或expired。
| 枚举值 | 描述 |
|---|---|
| created | 信封已创建 |
| submitted | 信封已发送以供签署 |
| completed | 信封的所有签署均已成功完成 |
| canceled | 信封因合作伙伴请求而取消 |
| expired | 信封因签署时间超时而过期 |
| 名称 | 类型 | 描述 |
|---|---|---|
| id | string | 信封的唯一标识符。 |
| status | string | 信封状态。 |
| expiration_date | string | 信封过期日期。 |
| signers | Signer | 描述信封签署人的 Signer 类型对象列表。 |
| documents | Document | 描述信封文件的 Document 类型对象列表。 |
Webhook
当所有签署人完成签署并生成档案后,将通过 Webhook 发送通知。 为此,需要通过支持团队(suporte@qitech.com.br)配置接收更新通知的端点地址,以及用于签署请求的 signature_key。
客户也可以使用轮询技术,尽管不推荐。这种情况下,只需不配置 webhook 端点,并使用注册查询端点进行轮询即可。
签名
Python 签名计算示例
hmac_obj = hmac.new(signature_key.encode('utf-8'), (endpoint + method + payload).encode('utf-8'), hashlib.sha1)
return hmac_obj.hexdigest()
为确保 webhook 端点收到的请求来自我们的服务器,请求的 Header Signature 中会发送 HMAC 签名,类似于认证过程。
在服务器端计算出签名的预期值后,需要将计算出的签名与发送的签名进行比较。如果签名匹配,说明请求来自我们的服务器,是可信的。
Webhook 调用示例:
{
"id": "479f8e5a-75e1-4a33-9d75-e0083e3c8e9c",
"status": "completed",
"webhook_type": "envelope_completed",
"signers": [
{
"id": "c15392dd-7859-4eae-a2b6-bf0f760a6d9b",
"biometry": {
"face_validation_available": true,
"fraud_base_flag": false,
"face_validation_score": 90
},
"liveness": {
"result": "live"
},
"document": {
"face_match_score": 85
}
}
]
}
| 名称 | 类型 | 描述 |
|---|---|---|
| id | string | 信封的唯一标识符。 |
| status | string | 信封状态。 |
| signer.id | string | 签署人的唯一标识符。 |
| signer.biometry.face_validation_available | boolean | 指示是否找到并验证了人脸。 |
| signer.biometry.fraud_base_flag | boolean | 指示签署人的人脸是否出现在欺诈数据库中。 |
| signer.biometry.face_validation_score | integer | 指示人脸验证评分。 |
| signer.liveness.result | string | 指示活体验证结果。可能的值为 live 或 spoof |
| signer.document.face_match_score | integer | 指示人脸匹配验证评分。 |
下载已签署的档案
如果所有签署人均已签署信封中的所有文件,信封状态将为 completed,每个文件的档案(包含签名和签署人数据)将可供下载。为此,请向端点 /sign/envelope/\{envelope_id\}/report 发送 GET 请求
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/report \
-H "Authorization: EXAMPLE_API_KEY"
如果请求成功,响应将是一个包含信封 id 和状态,以及文件 id 和生成档案 URL 列表的 JSON,示例如下:
响应示例
{
"id": "479f8e5a-75e1-4a33-9d75-e0083e3c8e9c",
"status": "available",
"documents_reports": [
{
"id": "a50ef632-842e-4622-8075-684b8c83a99e",
"url": "https://qisign-dossiers.com/06abda52-5bd1-46a1-8fa2-f616ba44b395.pdf"
}
]
}
- 每个文件的报告链接有效期为 24 小时。
- 信封报告的状态可以是
available或unavailable。 documents_reports属性包含信封文件列表,通过文件 id 和报告链接标识。
按已签署文件下载档案
如果所有签署人均已签署信封中的所有文件,信封状态将为 completed,每个已签署文件的档案(包含签名和签署人数据)将可供下载。为此,请向端点 /sign/envelope/\{envelope_id\}/document/{document_id}/report 发送 GET 请求
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/document/{document_id}/report \
-H "Authorization: EXAMPLE_API_KEY"
如果请求成功,响应将是一个包含 id、状态、URL 和文件档案 base64 的 JSON,示例如下:
响应示例
{
"id": "5b930d3d-3713-4c42-85d5-f8e9e44e30ce",
"status": "available",
"document_report_url": "https://qisign-dossiers.com/7bcf5868-784a-4356-85fb-dd72fd53cd4a.pdf",
"document_report": "vAsXDdsaGUsdIMIGxhIG1GU=..."
}
- 文件报告的链接有效期为 24 小时。
- 文件报告的状态可以是
available或unavailable。 document_report属性是以 base64 编码的 PDF 格式文件报告。
下载签署人的人脸照片
可以检索签署人的人脸图像。为此,请向端点 /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/face 发送 GET 请求
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/signer/\{signer_id\}/face \
-H "Authorization: EXAMPLE_API_KEY"
如果请求成功,响应将是一个包含 base64 编码图像的 JSON,示例如下:
响应示例
{
"face_image_url": "https://qisign-face-image.com/4fd09dab-6f3e-4ff5-bfed-6f7debfcde71.jpeg"
}
取消信封
要取消信封,请向端点 /sign/envelope/\{envelope_id\} 发送 PATCH 请求
curl -X PATCH \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY" \
-d '{
"status": "canceled"
}'
如果请求成功,响应将是一个包含信封状态的 JSON,示例如下:
响应示例
{
"status": "canceled"
}
下载签署人的文件照片
可以检索签署人的文件图像。为此,请向端点 /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document 发送 GET 请求
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document \
-H "Authorization: EXAMPLE_API_KEY"
如果请求成功,响应将是一个包含 base64 编码图像的 JSON,示例如下:
响应示例
{
"document_front_url": "https://qisign-personal-documents.com/bee17d70-b029-41e2-b76b-86f64a8f9213.jpeg",
"document_back_url": "https://qisign-personal-documents.com/faf38378-daa2-47b2-9d87-0bbc1f7c744c.jpeg"
}
查询签署人状态
要查看签署人的状态,请向端点 /sign/envelope/{envelope_id}/signer/{signer_id} 发送 GET 请求
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/signer/\{signer_id\} \
-H "Authorization: EXAMPLE_API_KEY"
如果请求成功,响应将是一个包含签署人状态的 JSON,示例如下:
响应示例
{
"name": "John Sample",
"email": "johnsample@test.com",
"status": "signed",
"signed_at": "2023-03-21T15:30:00.000Z"
}
| 名称 | 类型 | 描述 |
|---|---|---|
| name | string | 签署人姓名。 |
| string | 签署人电子邮件。 | |
| status | string | 签署人签署状态。 |
| signed_at | string | 最近签署的日期和时间,格式为 YYYY-MM-DDTHH:MM:SS.000Z。 |
HTTP 状态码
签名 API 使用以下 HTTP 返回状态标准,遵循 RFC 7231:
| HTTP 状态码 | 含义 | 描述 |
|---|---|---|
| 400 | Bad Request | 发送的请求存在格式错误。大多数情况下,我们会在消息正文中返回错误位置的说明。 |
| 401 | Unauthorized | 认证出现问题,请检查 API Key 是否正确以及是否在正确的 header 中,参见认证部分。 |
| 403 | Forbidden | 访问的端点为内部使用,该 API Key 无权使用。 |
| 404 | Not Found | 使用提供的密钥未找到所请求的数据。当请求无效的端点时也会返回此状态。 |
| 405 | Method Not Allowed | 使用的 HTTP 方法不适用于该端点。 |
| 406 | Not Acceptable | 请求正文中发送的数据无效。通常意味着发送的数据不是有效的 JSON。 |
| 409 | Conflict | 请求 ID 与之前已处理的 ID 对应。当向服务器发送重复请求时会返回此状态。 |
| 500 | Internal Server Error | 处理此请求时出现问题,遇到此错误时,我们的专家将自动收到通知并 立即开始分析和解决。 |
| 503 | Service Unavailable | 您遇到了我们服务器基础设施的计划或非计划中断。 |