基于DocuSign API实现DMS签署工作流的可行性咨询
可以实现,以下是基于.Net WebAPI集成DocuSign的具体方案
完全可以实现你描述的工作流,下面是针对.Net WebAPI环境的落地步骤和关键代码示例:
前期准备
- 注册DocuSign开发者账号,创建应用并获取集成密钥(Integrator Key)
- 配置JWT认证(适合服务端自动化场景):生成RSA密钥对,绑定具备发送信封权限的DocuSign用户
- 通过NuGet安装DocuSign官方SDK:
Install-Package DocuSign.eSign
工作流分步实现
1. 处理管理员上传文档并发起签署请求
在WebAPI中新增接口,接收文档文件、签署人姓名和邮箱,调用DocuSign API发送签署请求:
using DocuSign.eSign.Api; using DocuSign.eSign.Client; using DocuSign.eSign.Model; [HttpPost("initiate-sign")] public async Task<IActionResult> InitiateSign([FromForm] IFormFile document, [FromForm] string signerName, [FromForm] string signerEmail) { // 获取DocuSign访问令牌(JWT方式) var apiClient = new ApiClient("https://demo.docusign.net/restapi"); var jwtAuth = await apiClient.RequestJWTUserTokenAsync( integratorKey: "你的集成密钥", userId: "绑定的DocuSign用户ID", oauthBasePath: "account-d.docusign.com", privateKeyBytes: File.ReadAllBytes("RSA私钥文件路径"), expiresInHours: 1); apiClient.Configuration.DefaultHeader.Add("Authorization", $"Bearer {jwtAuth.AccessToken}"); // 构建信封对象 var envelopeDefinition = new EnvelopeDefinition { EmailSubject = "请签署文档", Status = "sent", // 直接发送信封 Documents = new List<Document> { new Document { DocumentBase64 = Convert.ToBase64String(await ReadFileBytes(document)), Name = document.FileName, DocumentId = "1" } }, Recipients = new Recipients { Signers = new List<Signer> { new Signer { Email = signerEmail, Name = signerName, RecipientId = "1", Tabs = new Tabs { SignHereTabs = new List<SignHere> { // 使用锚文本定位签署位置,文档中需包含{{sign_here}}标记 new SignHere { AnchorString = "{{sign_here}}", AnchorUnits = "pixels", AnchorYOffset = "10" } } } } } } }; // 发送信封 var envelopesApi = new EnvelopesApi(apiClient); var envelopeSummary = await envelopesApi.CreateEnvelopeAsync("你的DocuSign账号ID", envelopeDefinition); // 记录EnvelopeID到数据库,关联原文档 // 此处编写你的数据库操作逻辑,存储envelopeSummary.EnvelopeId与原文档的关联关系 return Ok(new { EnvelopeId = envelopeSummary.EnvelopeId }); } private async Task<byte[]> ReadFileBytes(IFormFile file) { using var ms = new MemoryStream(); await file.CopyToAsync(ms); return ms.ToArray(); }
2. 监听签署完成事件并获取签署后的文档
配置DocuSign Connect(Webhook),当签署完成时,DocuSign会向指定API地址发送通知。新增接口处理回调:
[HttpPost("docusign-webhook")] public async Task<IActionResult> DocuSignWebhook([FromBody] dynamic payload) { // 验证DocuSign请求签名(防止伪造请求) var signatureHeader = Request.Headers["X-DocuSign-Signature-1"].FirstOrDefault(); var requestBody = await new StreamReader(Request.Body).ReadToEndAsync(); var isValid = ValidateWebhookSignature(signatureHeader, requestBody, "你的Webhook密钥"); if (!isValid) return BadRequest(); // 判断是否签署完成 if (payload.eventType == "envelope-completed") { var envelopeId = payload.envelopeId; var apiClient = new ApiClient("https://demo.docusign.net/restapi"); // 重新获取访问令牌 var jwtAuth = await apiClient.RequestJWTUserTokenAsync(/* 同前文中的参数 */); apiClient.Configuration.DefaultHeader.Add("Authorization", $"Bearer {jwtAuth.AccessToken}"); // 下载签署后的文档 var envelopesApi = new EnvelopesApi(apiClient); var docStream = await envelopesApi.GetDocumentAsync("你的账号ID", envelopeId, "combined"); // combined表示下载合并后的完整文档 // 将文档存入自有数据库 // 此处编写数据库操作逻辑,将docStream转为字节流存入varbinary字段,更新文档状态为已签署 } return Ok(); } // 签名验证逻辑(需按DocuSign官方文档实现完整验证) private bool ValidateWebhookSignature(string signatureHeader, string payload, string webhookKey) { // 省略完整HMAC签名验证代码,可参考DocuSign官方文档实现 return true; }
3. 数据库存储逻辑
建议在文档表中新增字段:
SignedDocument:varbinary(max)类型,存储签署后的PDF字节流EnvelopeId:varchar类型,存储DocuSign信封IDSignStatus:tinyint类型,标记文档状态(待签署/已签署)
关键注意事项
- 环境切换:测试用
demo.docusign.net,生产环境改用www.docusign.net - 签署位置:若无需锚文本,可使用绝对坐标(X/Y值)定位签署框
- 错误处理:添加try-catch捕获DocuSign API异常,处理信封发送失败、回调验证失败等场景
- 权限控制:确保绑定的DocuSign用户具备
envelope:send和document:read权限
内容的提问来源于stack exchange,提问作者Adarsh s
相关产品推荐
相关产品推荐

