|
@@ -1,30 +1,99 @@
|
|
|
-import requests
|
|
|
|
|
import json
|
|
import json
|
|
|
|
|
+import logging
|
|
|
|
|
+import requests
|
|
|
|
|
+
|
|
|
from common.esigntool.esign_config import Config
|
|
from common.esigntool.esign_config import Config
|
|
|
from common.esigntool.esign_algorithm import buildSignJsonHeader
|
|
from common.esigntool.esign_algorithm import buildSignJsonHeader
|
|
|
-import time
|
|
|
|
|
from datetime import datetime
|
|
from datetime import datetime
|
|
|
|
|
+
|
|
|
|
|
+logger = logging.getLogger(__name__)
|
|
|
|
|
+
|
|
|
config = Config()
|
|
config = Config()
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+def _request(method: str, api_path: str, body: dict = None) -> str:
|
|
|
|
|
+ """统一的e签宝API请求方法
|
|
|
|
|
+
|
|
|
|
|
+ Args:
|
|
|
|
|
+ method: HTTP方法 (GET/POST)
|
|
|
|
|
+ api_path: API路径
|
|
|
|
|
+ body: 请求体字典
|
|
|
|
|
+
|
|
|
|
|
+ Returns:
|
|
|
|
|
+ 响应文本
|
|
|
|
|
+ """
|
|
|
|
|
+ headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
+ url = config.host + api_path
|
|
|
|
|
+
|
|
|
|
|
+ if body is not None:
|
|
|
|
|
+ data = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
+ resp = requests.request(method, url, data=data, headers=headers)
|
|
|
|
|
+ else:
|
|
|
|
|
+ resp = requests.request(method, url, headers=headers)
|
|
|
|
|
+ logger.debug("请求 %s %s, 响应: %s", method, api_path, resp.text)
|
|
|
|
|
+ return resp.text
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# ==================== 签署流程标题映射 ====================
|
|
|
|
|
+SIGN_FLOW_TITLES = {
|
|
|
|
|
+ "store_agreement": "商家入驻U店平台协议签署",
|
|
|
|
|
+ "alipay_auth": "支付宝授权函签署",
|
|
|
|
|
+ "wechat_pay_commitment": "微信支付承诺函签署",
|
|
|
|
|
+ "lawyer_agreement": "律所入驻U店平台协议签署",
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ==================== 签署位置配置 ====================
|
|
|
|
|
+SIGN_POSITIONS = {
|
|
|
|
|
+ "store_agreement": {
|
|
|
|
|
+ "alien": {"page": 7, "x": 294, "y": 668},
|
|
|
|
|
+ "signer": {"page": 7, "x": 114, "y": 666},
|
|
|
|
|
+ },
|
|
|
|
|
+ "alipay_auth": {
|
|
|
|
|
+ "alien": {"page": 1, "x": 535, "y": 555},
|
|
|
|
|
+ "signer": {"page": 1, "x": 535, "y": 431},
|
|
|
|
|
+ },
|
|
|
|
|
+ "wechat_pay_commitment": {
|
|
|
|
|
+ "signer": {"page": 1, "x": 535, "y": 515},
|
|
|
|
|
+ },
|
|
|
|
|
+ "lawyer_agreement": {
|
|
|
|
|
+ "alien": {"page": 6, "x": 336, "y": 418},
|
|
|
|
|
+ "signer": {"page": 6, "x": 145, "y": 418},
|
|
|
|
|
+ },
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ==================== 模板填充配置 ====================
|
|
|
|
|
+TEMPLATE_COMPONENT_VALUES = {
|
|
|
|
|
+ "store_agreement": {
|
|
|
|
|
+ "alien_name": "爱丽恩严(大连)商务科技有限公司",
|
|
|
|
|
+ "date": None, # 运行时填充
|
|
|
|
|
+ "one_name": None, # 运行时填充
|
|
|
|
|
+ "store_name": None, # 运行时填充
|
|
|
|
|
+ },
|
|
|
|
|
+ "lawyer_agreement": {
|
|
|
|
|
+ "alien_name": "爱丽恩严(大连)商务科技有限公司",
|
|
|
|
|
+ "alien_name_2": "爱丽恩严(大连)商务科技有限公司",
|
|
|
|
|
+ "law_firm_name": None, # 运行时填充
|
|
|
|
|
+ "law_firm_name_2": None, # 运行时填充
|
|
|
|
|
+ "signing_date": None, # 运行时填充
|
|
|
|
|
+ },
|
|
|
|
|
+ "alipay_auth": {},
|
|
|
|
|
+ "wechat_pay_commitment": {},
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def get_auth_flow_id(org_name, org_id, legal_rep_name, legal_rep_id):
|
|
def get_auth_flow_id(org_name, org_id, legal_rep_name, legal_rep_id):
|
|
|
"""获取机构认证&授权页面链接"""
|
|
"""获取机构认证&授权页面链接"""
|
|
|
- api_path = "/v3/org-auth-url"
|
|
|
|
|
- method = "POST"
|
|
|
|
|
body = {
|
|
body = {
|
|
|
"clientType": "ALL",
|
|
"clientType": "ALL",
|
|
|
"redirectConfig": {
|
|
"redirectConfig": {
|
|
|
"redirectUrl": "https://www.baidu.com"
|
|
"redirectUrl": "https://www.baidu.com"
|
|
|
},
|
|
},
|
|
|
"orgAuthConfig": {
|
|
"orgAuthConfig": {
|
|
|
- # "orgName": "爱丽恩严(大连)商务科技有限公司深圳分公司",
|
|
|
|
|
"orgName": org_name,
|
|
"orgName": org_name,
|
|
|
"orgInfo": {
|
|
"orgInfo": {
|
|
|
- # "orgIDCardNum": "91440300MADDW7XC4C",
|
|
|
|
|
"orgIDCardNum": org_id,
|
|
"orgIDCardNum": org_id,
|
|
|
"orgIDCardType": "CRED_ORG_USCC",
|
|
"orgIDCardType": "CRED_ORG_USCC",
|
|
|
- # "legalRepName": "彭少荣",
|
|
|
|
|
"legalRepName": legal_rep_name,
|
|
"legalRepName": legal_rep_name,
|
|
|
- # "legalRepIDCardNum": "362204198807182420",
|
|
|
|
|
"legalRepIDCardNum": legal_rep_id,
|
|
"legalRepIDCardNum": legal_rep_id,
|
|
|
"legalRepIDCardType": "CRED_PSN_CH_IDCARD"
|
|
"legalRepIDCardType": "CRED_PSN_CH_IDCARD"
|
|
|
},
|
|
},
|
|
@@ -38,295 +107,150 @@ def get_auth_flow_id(org_name, org_id, legal_rep_name, legal_rep_id):
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
- # "authorizeConfig": {
|
|
|
|
|
- # "authorizedScopes": [
|
|
|
|
|
- # "get_org_identity_info",
|
|
|
|
|
- # "get_psn_identity_info",
|
|
|
|
|
- # "org_initiate_sign",
|
|
|
|
|
- # "manage_org_resource"
|
|
|
|
|
- # ]
|
|
|
|
|
- # },
|
|
|
|
|
"notifyUrl": "http://120.26.186.130:33333/api/store/esign/callback_auth",
|
|
"notifyUrl": "http://120.26.186.130:33333/api/store/esign/callback_auth",
|
|
|
"transactorUseSeal": True
|
|
"transactorUseSeal": True
|
|
|
}
|
|
}
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
- body_json = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, data=body_json, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
- return resp.text
|
|
|
|
|
|
|
+ return _request("POST", "/v3/org-auth-url", body)
|
|
|
|
|
|
|
|
-# get_auth_flow_id()
|
|
|
|
|
|
|
|
|
|
def get_template_detail():
|
|
def get_template_detail():
|
|
|
"""查询合同模板中控件详情"""
|
|
"""查询合同模板中控件详情"""
|
|
|
- api_path = f"/v3/doc-templates/{config.templates_id}"
|
|
|
|
|
- method = "GET"
|
|
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
-
|
|
|
|
|
-def fill_in_template(name):
|
|
|
|
|
- """填写模板生成文件"""
|
|
|
|
|
- api_path = "/v3/files/create-by-doc-template"
|
|
|
|
|
- method = "POST"
|
|
|
|
|
|
|
+ return _request("GET", f"/v3/doc-templates/{config.templates_id}")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def fill_in_template(name, contract_type="store_agreement"):
|
|
|
|
|
+ """填写模板生成文件
|
|
|
|
|
+
|
|
|
|
|
+ Args:
|
|
|
|
|
+ name: 商家/律所名称
|
|
|
|
|
+ contract_type: 合同类型 (store_agreement/lawyer_agreement/alipay_auth/wechat_pay_commitment)
|
|
|
|
|
+ """
|
|
|
|
|
+ today = datetime.now().strftime("%Y年%m月%d日")
|
|
|
|
|
+ base_values = TEMPLATE_COMPONENT_VALUES.get(contract_type, {})
|
|
|
|
|
+
|
|
|
|
|
+ # 根据合同类型填充动态字段
|
|
|
|
|
+ dynamic_values = {
|
|
|
|
|
+ "store_agreement": {"store_name": name, "one_name": name, "date": today},
|
|
|
|
|
+ "lawyer_agreement": {"law_firm_name": name, "law_firm_name_2": name, "signing_date": today},
|
|
|
|
|
+ }.get(contract_type, {})
|
|
|
|
|
+
|
|
|
|
|
+ components = [
|
|
|
|
|
+ {"componentKey": key, "componentValue": value}
|
|
|
|
|
+ for key, value in {**base_values, **dynamic_values}.items()
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
body = {
|
|
body = {
|
|
|
- "docTemplateId": config.templates_id,
|
|
|
|
|
- "fileName": "U店在这-商户入驻协议",
|
|
|
|
|
- "components": [
|
|
|
|
|
- {
|
|
|
|
|
- "componentKey": "alien_name",
|
|
|
|
|
- "componentValue": "爱丽恩严(大连)商务科技有限公司"
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- "componentKey": "store_name",
|
|
|
|
|
- "componentValue": name
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- "componentKey": "date",
|
|
|
|
|
- "componentValue": datetime.now().strftime("%Y年%m月%d日")
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- "componentKey": "one_name",
|
|
|
|
|
- "componentValue": name
|
|
|
|
|
- },
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ "docTemplateId": config.templates_map.get(contract_type, ""),
|
|
|
|
|
+ "fileName": config.template_file_names.get(contract_type, ""),
|
|
|
|
|
+ "components": components
|
|
|
}
|
|
}
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
- body_json = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, data=body_json, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
- return resp.text
|
|
|
|
|
|
|
+ return _request("POST", "/v3/files/create-by-doc-template", body)
|
|
|
|
|
+
|
|
|
|
|
|
|
|
def get_contract_detail(file_id):
|
|
def get_contract_detail(file_id):
|
|
|
"""查询PDF模板填写后文件"""
|
|
"""查询PDF模板填写后文件"""
|
|
|
- api_path = f"/v3/files/{file_id}"
|
|
|
|
|
- method = "GET"
|
|
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
- return resp.text
|
|
|
|
|
|
|
+ return _request("GET", f"/v3/files/{file_id}")
|
|
|
|
|
|
|
|
-# get_contract_detail("f0371b4ae7c64c8ca16be3bf031d1d6e")
|
|
|
|
|
-# def create_by_file(file_id, file_name, contact_phone, merchant_name):
|
|
|
|
|
-# """基于文件发起签署"""
|
|
|
|
|
-# api_path = "/v3/sign-flow/create-by-file"
|
|
|
|
|
-# method = "POST"
|
|
|
|
|
-# body = {
|
|
|
|
|
-# "docs": [
|
|
|
|
|
-# {
|
|
|
|
|
-# "fileId": file_id,
|
|
|
|
|
-# "fileName": f"{file_name}.pdf"
|
|
|
|
|
-# }
|
|
|
|
|
-# ],
|
|
|
|
|
-# "signFlowConfig": {
|
|
|
|
|
-# "signFlowTitle": "商家入驻U店的签署协议", # 请设置当前签署任务的主题
|
|
|
|
|
-# "autoFinish": True,
|
|
|
|
|
-# "noticeConfig": {
|
|
|
|
|
-# "noticeTypes": "" #
|
|
|
|
|
-# # """通知类型,通知发起方、签署方、抄送方,默认不通知(值为""空字符串),允许多种通知方式,请使用英文逗号分隔
|
|
|
|
|
-# #
|
|
|
|
|
-# # "" - 不通知(默认值)
|
|
|
|
|
-# #
|
|
|
|
|
-# # 1 - 短信通知(如果套餐内带“分项”字样,请确保开通【电子签名流量费(分项)认证】中的子项:【短信服务】,否则短信通知收不到)
|
|
|
|
|
-# #
|
|
|
|
|
-# # 2 - 邮件通知
|
|
|
|
|
-# #
|
|
|
|
|
-# # 3 - 钉钉工作通知(需使用e签宝钉签产品)
|
|
|
|
|
-# #
|
|
|
|
|
-# # 5 - 微信通知(用户需关注“e签宝电子签名”微信公众号且使用过e签宝微信小程序)
|
|
|
|
|
-# #
|
|
|
|
|
-# # 6 - 企业微信通知(需要使用e签宝企微版产品)
|
|
|
|
|
-# #
|
|
|
|
|
-# # 7 - 飞书通知(需要使用e签宝飞书版产品)
|
|
|
|
|
-# #
|
|
|
|
|
-# # 补充说明:
|
|
|
|
|
-# #
|
|
|
|
|
-# # 1、2:个人账号中需要绑定短信/邮件才有对应的通知方式;
|
|
|
|
|
-# # 3、5、6、7:仅限e签宝正式环境调用才会有。"""
|
|
|
|
|
-# },
|
|
|
|
|
-# "notifyUrl": "http://120.26.186.130:33333:/api/store/esign/callback", # 接收相关回调通知的Web地址,
|
|
|
|
|
-# "redirectConfig": {
|
|
|
|
|
-# "redirectUrl": "https://www.esign.cn/"
|
|
|
|
|
-# }
|
|
|
|
|
-# },
|
|
|
|
|
-# "signers": [
|
|
|
|
|
-# {
|
|
|
|
|
-# "signConfig": {
|
|
|
|
|
-# "signOrder": 1
|
|
|
|
|
-# },
|
|
|
|
|
-# "signerType": 1,
|
|
|
|
|
-# "signFields": [
|
|
|
|
|
-# {
|
|
|
|
|
-# "customBizNum": "9527", # 开发者自定义业务编号
|
|
|
|
|
-# "fileId": file_id, #签署区所在待签署文件ID 【注】这里的fileId需先添加在docs数组中,否则会报错“参数错误: 文件id不在签署流程中”。
|
|
|
|
|
-# "normalSignFieldConfig": {
|
|
|
|
|
-# "autoSign": True,
|
|
|
|
|
-# "signFieldStyle": 1,
|
|
|
|
|
-# "signFieldPosition": {
|
|
|
|
|
-# "positionPage": "7",
|
|
|
|
|
-# "positionX": 294, # 获取需要盖章的位置: https://open.esign.cn/tools/seal-position
|
|
|
|
|
-# "positionY": 668
|
|
|
|
|
-# }
|
|
|
|
|
-# }
|
|
|
|
|
-# }
|
|
|
|
|
-# ]
|
|
|
|
|
-# },
|
|
|
|
|
-# {
|
|
|
|
|
-# "psnSignerInfo": {
|
|
|
|
|
-# "psnAccount": contact_phone,
|
|
|
|
|
-# "psnInfo": {
|
|
|
|
|
-# "psnName": merchant_name
|
|
|
|
|
-# }
|
|
|
|
|
-# },
|
|
|
|
|
-# "signConfig": {
|
|
|
|
|
-# "forcedReadingTime": 10,
|
|
|
|
|
-# "signOrder": 2
|
|
|
|
|
-# },
|
|
|
|
|
-# "signerType": 0,
|
|
|
|
|
-# "signFields": [
|
|
|
|
|
-# {
|
|
|
|
|
-# "customBizNum": "9527",
|
|
|
|
|
-# "fileId": file_id,
|
|
|
|
|
-# "normalSignFieldConfig": {
|
|
|
|
|
-# "signFieldStyle": 1,
|
|
|
|
|
-# "signFieldPosition": {
|
|
|
|
|
-# "positionPage": "7",
|
|
|
|
|
-# "positionX": 114, # 获取需要盖章的位置: https://open.esign.cn/tools/seal-position
|
|
|
|
|
-# "positionY": 666
|
|
|
|
|
-# }
|
|
|
|
|
-# }
|
|
|
|
|
-# }
|
|
|
|
|
-# ]
|
|
|
|
|
-# }
|
|
|
|
|
-# ]
|
|
|
|
|
-# }
|
|
|
|
|
-# json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
-# body_json = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
-# resp = requests.request(method, config.host + api_path, data=body_json, headers=json_headers)
|
|
|
|
|
-# print(resp.text)
|
|
|
|
|
-# return resp.text
|
|
|
|
|
-
|
|
|
|
|
-def create_by_file(file_id, file_name, contact_phone, store_name, merchant_name, ord_id):
|
|
|
|
|
- """基于文件发起签署"""
|
|
|
|
|
- api_path = "/v3/sign-flow/create-by-file"
|
|
|
|
|
- method = "POST"
|
|
|
|
|
- body = {
|
|
|
|
|
- "docs": [
|
|
|
|
|
- {
|
|
|
|
|
|
|
+
|
|
|
|
|
+def _build_alien_signer(file_id, position):
|
|
|
|
|
+ """构建平台方(爱丽恩严)签署人配置"""
|
|
|
|
|
+ return {
|
|
|
|
|
+ "signConfig": {"signOrder": 1},
|
|
|
|
|
+ "signerType": 1,
|
|
|
|
|
+ "signFields": [{
|
|
|
|
|
+ "customBizNum": "9527",
|
|
|
"fileId": file_id,
|
|
"fileId": file_id,
|
|
|
- "fileName": f"{file_name}.pdf"
|
|
|
|
|
- }
|
|
|
|
|
- ],
|
|
|
|
|
- "signFlowConfig": {
|
|
|
|
|
- "signFlowTitle": "商家入驻U店平台协议签署",
|
|
|
|
|
- "autoFinish": True,
|
|
|
|
|
- "noticeConfig": {
|
|
|
|
|
- "noticeTypes": "1,2"
|
|
|
|
|
- },
|
|
|
|
|
- "notifyUrl": "http://120.26.186.130:33333:/api/store/esign/callback",
|
|
|
|
|
- "redirectConfig": {
|
|
|
|
|
- "redirectUrl": "https://www.esign.cn/"
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- "signers": [
|
|
|
|
|
- {
|
|
|
|
|
- "signConfig": {
|
|
|
|
|
- "signOrder": 1
|
|
|
|
|
- },
|
|
|
|
|
- "signerType": 1,
|
|
|
|
|
- "signFields": [
|
|
|
|
|
- {
|
|
|
|
|
- "customBizNum": "9527",
|
|
|
|
|
- "fileId": file_id,
|
|
|
|
|
- "normalSignFieldConfig": {
|
|
|
|
|
- "autoSign": True,
|
|
|
|
|
- "signFieldStyle": 1,
|
|
|
|
|
- "signFieldPosition": {
|
|
|
|
|
- "positionPage": "7",
|
|
|
|
|
- "positionX": 294,
|
|
|
|
|
- "positionY": 668
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ "normalSignFieldConfig": {
|
|
|
|
|
+ "autoSign": True,
|
|
|
|
|
+ "signFieldStyle": 1,
|
|
|
|
|
+ "signFieldPosition": {
|
|
|
|
|
+ "positionPage": str(position["page"]),
|
|
|
|
|
+ "positionX": position["x"],
|
|
|
|
|
+ "positionY": position["y"]
|
|
|
}
|
|
}
|
|
|
- ]
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- "orgSignerInfo": {
|
|
|
|
|
- "orgName": store_name,
|
|
|
|
|
- "orgInfo": {
|
|
|
|
|
- "orgIDCardNum": ord_id, # "91440300MADDW7XC4C"
|
|
|
|
|
- "orgIDCardType": "CRED_ORG_USCC"
|
|
|
|
|
- },
|
|
|
|
|
- "transactorInfo": {
|
|
|
|
|
- "psnAccount": contact_phone,
|
|
|
|
|
- "psnInfo": {
|
|
|
|
|
- "psnName": merchant_name
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
- "signConfig": {
|
|
|
|
|
- "forcedReadingTime": 10,
|
|
|
|
|
- "signOrder": 2
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ }]
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def _build_org_signer(file_id, position, signer_name, signer_id_num, psn_account, psn_name):
|
|
|
|
|
+ """构建签署方(商家/律所)签署人配置"""
|
|
|
|
|
+ return {
|
|
|
|
|
+ "signConfig": {"forcedReadingTime": 10, "signOrder": 2},
|
|
|
|
|
+ "signerType": 1,
|
|
|
|
|
+ "orgSignerInfo": {
|
|
|
|
|
+ "orgName": signer_name,
|
|
|
|
|
+ "orgInfo": {
|
|
|
|
|
+ "orgIDCardNum": signer_id_num,
|
|
|
|
|
+ "orgIDCardType": "CRED_ORG_USCC"
|
|
|
},
|
|
},
|
|
|
- "signerType": 1,
|
|
|
|
|
- "signFields": [
|
|
|
|
|
- {
|
|
|
|
|
- "customBizNum": "自定义编码001",
|
|
|
|
|
- "fileId": file_id,
|
|
|
|
|
- "normalSignFieldConfig": {
|
|
|
|
|
- "signFieldStyle": 1,
|
|
|
|
|
- "signFieldPosition": {
|
|
|
|
|
- "positionPage": "7",
|
|
|
|
|
- "positionX": 114,
|
|
|
|
|
- "positionY": 666
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ "transactorInfo": {
|
|
|
|
|
+ "psnAccount": psn_account,
|
|
|
|
|
+ "psnInfo": {"psnName": psn_name}
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ "signFields": [{
|
|
|
|
|
+ "customBizNum": "自定义编码001",
|
|
|
|
|
+ "fileId": file_id,
|
|
|
|
|
+ "normalSignFieldConfig": {
|
|
|
|
|
+ "signFieldStyle": 1,
|
|
|
|
|
+ "signFieldPosition": {
|
|
|
|
|
+ "positionPage": str(position["page"]),
|
|
|
|
|
+ "positionX": position["x"],
|
|
|
|
|
+ "positionY": position["y"]
|
|
|
}
|
|
}
|
|
|
- ]
|
|
|
|
|
- }
|
|
|
|
|
- ]
|
|
|
|
|
-}
|
|
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
- body_json = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, data=body_json, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
- return resp.text
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ }]
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def create_by_file(file_id, file_name, signer_name, signer_id_num, psn_account, psn_name, contract_type="store_agreement"):
|
|
|
|
|
+ """基于文件发起签署
|
|
|
|
|
+
|
|
|
|
|
+ Args:
|
|
|
|
|
+ file_id: 文件ID
|
|
|
|
|
+ file_name: 文件名
|
|
|
|
|
+ signer_name: 签署方名称
|
|
|
|
|
+ signer_id_num: 签署方证件号
|
|
|
|
|
+ psn_account: 经办人账号标识(手机号/邮箱)
|
|
|
|
|
+ psn_name: 经办人姓名
|
|
|
|
|
+ contract_type: 合同类型 (store_agreement/alipay_auth/wechat_pay_commitment/lawyer_agreement)
|
|
|
|
|
+ """
|
|
|
|
|
+ positions = SIGN_POSITIONS.get(contract_type, SIGN_POSITIONS["store_agreement"])
|
|
|
|
|
+
|
|
|
|
|
+ signers = []
|
|
|
|
|
+ if positions.get("alien"):
|
|
|
|
|
+ signers.append(_build_alien_signer(file_id, positions["alien"]))
|
|
|
|
|
+ if positions.get("signer"):
|
|
|
|
|
+ signers.append(_build_org_signer(file_id, positions["signer"], signer_name, signer_id_num, psn_account, psn_name))
|
|
|
|
|
+
|
|
|
|
|
+ body = {
|
|
|
|
|
+ "docs": [{"fileId": file_id, "fileName": f"{file_name}.pdf"}],
|
|
|
|
|
+ "signFlowConfig": {
|
|
|
|
|
+ "signFlowTitle": SIGN_FLOW_TITLES.get(contract_type, "合同签署"),
|
|
|
|
|
+ "autoFinish": True,
|
|
|
|
|
+ "noticeConfig": {"noticeTypes": "1,2"},
|
|
|
|
|
+ "notifyUrl": "http://120.26.186.130:33333:/api/store/esign/callback",
|
|
|
|
|
+ "redirectConfig": {"redirectUrl": "https://www.esign.cn/"},
|
|
|
|
|
+ },
|
|
|
|
|
+ "signers": signers
|
|
|
|
|
+ }
|
|
|
|
|
+ return _request("POST", "/v3/sign-flow/create-by-file", body)
|
|
|
|
|
|
|
|
-def sign_url(sign_flow_id, contact_phone):
|
|
|
|
|
|
|
+
|
|
|
|
|
+def sign_url(sign_flow_id, psn_account):
|
|
|
"""获取签署页面链接"""
|
|
"""获取签署页面链接"""
|
|
|
- api_path = f"/v3/sign-flow/{sign_flow_id}/sign-url"
|
|
|
|
|
- method = "POST"
|
|
|
|
|
body = {
|
|
body = {
|
|
|
- "signFlowId": sign_flow_id,
|
|
|
|
|
- "clientType": "ALL",
|
|
|
|
|
- "needLogin": False,
|
|
|
|
|
- "operator": {
|
|
|
|
|
- "psnAccount": contact_phone
|
|
|
|
|
- },
|
|
|
|
|
- "urlType": 2
|
|
|
|
|
-}
|
|
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
- body_json = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, data=body_json, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
- return resp.text
|
|
|
|
|
|
|
+ "signFlowId": sign_flow_id,
|
|
|
|
|
+ "clientType": "ALL",
|
|
|
|
|
+ "needLogin": False,
|
|
|
|
|
+ "operator": {"psnAccount": psn_account},
|
|
|
|
|
+ "urlType": 2
|
|
|
|
|
+ }
|
|
|
|
|
+ return _request("POST", f"/v3/sign-flow/{sign_flow_id}/sign-url", body)
|
|
|
|
|
+
|
|
|
|
|
|
|
|
def file_download_url(sign_flow_id):
|
|
def file_download_url(sign_flow_id):
|
|
|
"""下载已签署文件及附属材料"""
|
|
"""下载已签署文件及附属材料"""
|
|
|
- api_path = f"/v3/sign-flow/{sign_flow_id}/file-download-url"
|
|
|
|
|
- method = "POST"
|
|
|
|
|
- body = {
|
|
|
|
|
- "urlAvailableDate": "3600"
|
|
|
|
|
-}
|
|
|
|
|
- json_headers = buildSignJsonHeader(config.appId, config.scert, method, api_path, body=body)
|
|
|
|
|
- body_json = json.dumps(body, separators=(",", ":"), ensure_ascii=False)
|
|
|
|
|
- resp = requests.request(method, config.host + api_path, data=body_json, headers=json_headers)
|
|
|
|
|
- print(resp.text)
|
|
|
|
|
- return resp.text
|
|
|
|
|
-
|
|
|
|
|
-# fill_in_template("我勒个去")
|
|
|
|
|
-# sing_data = create_by_file("41bd938c47394e6b9bf4a491949c161e", "U店在这-商户入驻协议", "13503301290", "孟骞康")
|
|
|
|
|
-# sign_json = json.loads(sing_data)
|
|
|
|
|
-# sing_id = sign_json["data"]["signFlowId"]
|
|
|
|
|
-# sign_url("", "13503301290")
|
|
|
|
|
-# file_download_url("15156afb603e4145b112ad6eab0815d5")
|
|
|
|
|
|
|
+ body = {"urlAvailableDate": "3600"}
|
|
|
|
|
+ return _request("POST", f"/v3/sign-flow/{sign_flow_id}/file-download-url", body)
|