b2b_autosign_demo.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # -*- coding: UTF-8 -*-
  2. import time
  3. import esigntool
  4. import requests
  5. from esigntool import esign_run_print_outer
  6. from esigntool.esign_file import fileHelp
  7. """
  8. * 本文件适用于平台方自动+企业用户自动签署场景
  9. * 基本流程如下:
  10. * 1、企业用户将印章授权给平台方,可通过登录e签宝官网企业控制台完成,或者通过印章开放服务完成:https://open.esign.cn/doc/opendoc/seal3/qkxyha
  11. * 2、发起签署时,设置signFields入参规则:signers.orgSignerInfo对象中的orgId为平台方企业账号id,assignedSealId为授权企业的印章id,autoSign设置为true
  12. * 3、流程完结后,下载签署后文件
  13. """
  14. config = esigntool.config() # 初始化配置类
  15. @esign_run_print_outer
  16. def findOrgIdentityInfo(orgName):
  17. """
  18. 查询机构认证信息
  19. :return:
  20. """
  21. api_path = "/v3/organizations/identity-info?orgName={}".format(orgName)
  22. method = esigntool.httpMethodEnum.GET
  23. if orgName == "":
  24. print("请设置实名企业名称")
  25. exit()
  26. # 签名并构造签名鉴权json请求头
  27. json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert, method, esigntool.apiPathSort(api_path))
  28. # 发起请求
  29. resp = requests.request(method, config.host + api_path, json=None, headers=json_headers)
  30. print(resp.text)
  31. orgId = resp.json()['data']['orgId']
  32. return orgId
  33. @esign_run_print_outer
  34. def getFileUploadUrl(file):
  35. """
  36. 获取文件上传地址
  37. :return:
  38. """
  39. contentType = "application/pdf" # 声明请求变量
  40. body = {
  41. "contentMd5": file.contentMd5,
  42. "contentType": contentType,
  43. "convert2Pdf": False,
  44. "fileName": file.fileName,
  45. "fileSize": file.fileSize
  46. } # 构建请求参数body体
  47. api_path = "/v3/files/file-upload-url"
  48. method = esigntool.httpMethodEnum.POST
  49. json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert,
  50. method, api_path, body) # 签名并构造签名鉴权json请求头
  51. resp = requests.request(method, config.host + api_path, json=body, headers=json_headers) # 发送请求
  52. fileUploadUrl = resp.json()['data']['fileUploadUrl'] # 获取文件上传路径
  53. fileId = resp.json()['data']['fileId']
  54. print(resp.text)
  55. return fileUploadUrl, fileId
  56. @esign_run_print_outer
  57. def fileStreamUpload(binfile, fileUploadUrl):
  58. """
  59. 文件流上传服务器
  60. :return:
  61. """
  62. contentMd5 = file.contentMd5 # 声明请求变量
  63. contentType = "application/pdf" # 声明请求变量
  64. method = esigntool.httpMethodEnum.PUT # 声明请求方法
  65. json_headers = esigntool.buildFileUploadHeader(contentType, contentMd5) # 构建请求头
  66. resp = requests.request(method, fileUploadUrl, data=binfile, headers=json_headers) # 发送请求
  67. print(resp.text)
  68. return resp
  69. @esign_run_print_outer
  70. def signFlowCreateByFile(fileId, orgId, sealId):
  71. """
  72. 基于文件发起签署
  73. :return:
  74. """
  75. body = {
  76. "docs": [
  77. {
  78. "fileId": fileId,
  79. "fileName": "xx企业劳动合同.pdf"
  80. }
  81. ],
  82. "attachments": [
  83. {
  84. "fileId": fileId,
  85. "fileName": "入职材料.pdf"
  86. }
  87. ],
  88. "signers": [
  89. {
  90. "orgSignerInfo": {
  91. "orgId": orgId
  92. },
  93. "signConfig": {
  94. "signOrder": 1
  95. },
  96. "signFields": [
  97. {
  98. "customBizNum": "自定义编码",
  99. "fileId": fileId,
  100. "normalSignFieldConfig": {
  101. "autoSign": True,
  102. "signFieldPosition": {
  103. "positionPage": "1",
  104. "positionX": 300,
  105. "positionY": 300
  106. },
  107. "signFieldStyle": 1
  108. }
  109. }
  110. ],
  111. "signerType": 1
  112. },
  113. {
  114. "orgSignerInfo": {
  115. "orgId": orgId
  116. },
  117. "signConfig": {
  118. "signOrder": 1
  119. },
  120. "signFields": [
  121. {
  122. "customBizNum": "自定义编码",
  123. "fileId": fileId,
  124. "normalSignFieldConfig": {
  125. "autoSign": True,
  126. "assignedSealId": sealId, # 传入授权后的印章ID
  127. "signFieldPosition": {
  128. "positionPage": "1",
  129. "positionX": 100,
  130. "positionY": 200
  131. },
  132. "signFieldStyle": 1
  133. }
  134. }
  135. ],
  136. "signerType": 1
  137. }
  138. ],
  139. "signFlowConfig": {
  140. "autoFinish": True, # 自动完结,为false的时候需要单独调用对应完结接口
  141. "autoStart": True, # 自动开启,为false的时候需要单独调用对应开启接口
  142. "noticeConfig": {
  143. "noticeTypes": "1"
  144. },
  145. "notifyUrl": "http://xx.xx.86.172:8081/asyn/notify",
  146. "redirectConfig": {
  147. "redirectDelayTime": "3",
  148. "redirectUrl": "http://www.esign.cn"
  149. },
  150. "signConfig": {
  151. "availableSignClientTypes": "1",
  152. "showBatchDropSealButton": True
  153. },
  154. "signFlowTitle": "企业员工劳动合同签署"
  155. }
  156. } # 构建请求body体
  157. api_path = "/v3/sign-flow/create-by-file" # 拼接请求路径
  158. method = esigntool.httpMethodEnum.POST # 声明请求方法
  159. json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert,
  160. method, api_path, body) # 签名并构造签名鉴权json请求头
  161. resp = requests.request(method, config.host + api_path, json=body, headers=json_headers) # 发送请求
  162. print(resp.text)
  163. sign_flowId = resp.json()['data']['signFlowId']
  164. return sign_flowId
  165. @esign_run_print_outer
  166. def fileDownloadUrl(sign_flowId):
  167. """
  168. 下载已签署文件及附属材料
  169. :return:
  170. """
  171. api_path = "/v3/sign-flow/{}/file-download-url".format(sign_flowId) # 拼接请求路径
  172. method = esigntool.httpMethodEnum.GET # 声明请求方法
  173. json_headers = esigntool.buildSignJsonHeader(config.appId, config.scert,
  174. method, api_path) # 签名并构造签名鉴权json请求头
  175. resp = requests.request(method, config.host + api_path, json=None, headers=json_headers) # 发送请求
  176. print(resp.text)
  177. return resp
  178. if __name__ == '__main__':
  179. if config.appId == "" or config.scert == "":
  180. print("请设置应用Appid和应用Secret")
  181. exit()
  182. fileUrl = "D://**文件//1.pdf" # 本地文件路径
  183. orgName = "**企业" # 平台自身企业名称,即appid所属的企业名称
  184. sealId = "*******fef" # 通过印章开放服务来获取印章ID
  185. orgId = findOrgIdentityInfo(orgName) # 查询平台自身实名帐号ID
  186. file = fileHelp(fileUrl) # 初始化文件辅助类
  187. fileUploadUrl, fileId = getFileUploadUrl(file) # 获取文件ID&文件上传路径
  188. fileStreamUpload(file.getBinFile(), fileUploadUrl) # 上传文件流
  189. sign_flowId = signFlowCreateByFile(fileId, orgId, sealId) # 发起一步签署:主动发送签署短信给签署用户
  190. time.sleep(2)
  191. fileDownloadUrl(sign_flowId) # 合同结束后(个人用户签署完成后),下载签署后合同