【API之电子签章方案1】明道云对接集成法大大

6 / 336
什么是电子签章

  电子签章是电子签名的一种表现形式,利用图像处理技术将电子签名操作转化为与纸质文件盖章操作相同的可视效果,同时利用电子签名技术保障电子信息的真实性和完整性以及签名人的不可否认性。企业用途最广的就是电子合同,它是《合同法》认可的一种合同形式。但由于电子合同以数据电文为载体,涉及到一系列的技术标准,其中最核心、也最重要的是电子签名技术。 这里说的电子签名是一串数据或代码,它采用数字证书的技术手段来确定签名人的真实身份。根据国家法律规定,只有使用可靠电子签名签订的电子合同才具有法律效力.
  19 年的疫情也促使企业数字化快速发展,明道云也被客户了解,使用与推广。客户通过明道云搭建业务系统,使企业流程/数据正常运转与留存。业务得以保障。那人事合同 商业合同呢?如何数字化?怎么与明道云结合?这也是客户遇到的问题。
  客户再找解决方案,也接触到了法大大 e 签宝 等电子签章产品。 那么今天小编就在这里介绍下【明道云与法大大的集成对接】

  1. 申请密钥
      官网联系客服--> 开通申请--邮箱收到 密钥信息及 API 对接文档
  2. 注册账号及证书申请 印章上传
    image.png
  • 为用户注册法⼤大账号 account_register.api
  • 根据账号类型调用对应的接口
    get_person_verify_url.api 个⼈实名认证⻚面接⼝
    get_company_verify_url.api 企业实名认证⻚⾯接⼝
  • 申请实名证书 apply_cert.api
代码块示例
1.账号注册参数加密
var account_type = input.account_type=='个人'?'1':'2';
var v = input.v;
var app_secret = input.app_secret;
var app_id = input.app_id;
var crypto = require('crypto');
function pad2(n) { return n < 10 ? '0' + n : n }
function generateTimeReqestNumber() {
            var datee = new Date();
var localTime = datee .getTime();
var localOffset=datee .getTimezoneOffset()*60000; //获得当地时间偏移的毫秒数
var utc = localTime + localOffset; //utc即GMT时间
var offset =8; //以北京时间为例,东8区
var hawaii = utc + (3600000*offset); 
	var date = new Date(hawaii);
	date.setHours(date.getHours());
	return date.getFullYear().toString() + pad2(date.getMonth() + 1) + pad2(date.getDate()) + pad2(date.getHours()) + pad2(date.getMinutes()) + pad2(date.getSeconds());
}
function sha1(s) {
	var hash = crypto.createHash('sha1');
	hash.update(s);
	return hash.digest('hex').toUpperCase();
}
function md5(s) {
	var hash = crypto.createHash('md5');
	hash.update(s);
	return hash.digest('hex').toUpperCase();
}
function base64(s) {
	var b = new Buffer.from(s);
	return b.toString('base64');
}
function ast(s) {
	return s.split('').sort().join('');
}

var timestamp = generateTimeReqestNumber();	
var msg_digest = base64( sha1( app_id + md5(timestamp) + sha1(app_secret + account_type + input.openid)));
return {ts: timestamp, sign: msg_digest, appid: app_id, v: v, openid: input.open_id, accounttype: account_type};

1.2 调用注册方法
var url=input.url+'/api/account_register.api';
const fetch = require('node-fetch'); 
const FormData= require('form-data');
var result={};
let data= new FormData();
data.append("app_id",input.appid)
data.append("v",input.v)
data.append("timestamp",input.ts)
data.append("msg_digest",input.sign)
data.append("open_id",input.openid)
data.append("account_type",input.accounttype)
async function getAll(data){
    const res = await   fetch(url,{
    method:"post",
    body:data
}).then(function(response){
    if(response.ok){
 return  response.json();   
    }else{
  return   {"error":"无数据"};
}
}).catch(function(err){
   return   {"error":"Fetch错误:"+err};
});
    const result = await   res;
    return result;
}
result=await  getAll(data);
output={result:result}

2申请实名认证参数加密
var v = input.v;
var app_secret = input.appsecret;
var aid = input.aid;
var crypto = require('crypto');
var data={"customer_id":input.customerid,
"verified_way":3,
"page_modify":1,
"option":"add",
"lang":"zh",
"organization_type":0,
"notify_url":"换为你的接受地址"}

function pad2(n) { return n < 10 ? '0' + n : n }
function generateTimeReqestNumber() {
            var datee = new Date();
var localTime = datee .getTime();
var localOffset=datee .getTimezoneOffset()*60000; //获得当地时间偏移的毫秒数
var utc = localTime + localOffset; //utc即GMT时间
var offset =8; //以北京时间为例,东8区
var hawaii = utc + (3600000*offset); 
	var date = new Date(hawaii);
	date.setHours(date.getHours());
	return date.getFullYear().toString() + pad2(date.getMonth() + 1) + pad2(date.getDate()) + pad2(date.getHours()) + pad2(date.getMinutes()) + pad2(date.getSeconds());
}
function sha1(s) {
	var hash = crypto.createHash('sha1');
	hash.update(s);
	return hash.digest('hex').toUpperCase();
}
function md5(s) {
	var hash = crypto.createHash('md5');
	hash.update(s);
	return hash.digest('hex').toUpperCase();
}
function base64(s) {
	var b = new Buffer.from(s);
	return b.toString('base64');
}
function ast(s) {
	return s.split('').sort().join('');
}
var newData = {},params='';
Object.keys(data).sort().map(key => {
  newData[key]=data[key]
  params=params+=data[key];
})
var timestamp = generateTimeReqestNumber();	
var msg_digest = base64( sha1(aid + md5(timestamp) + sha1(app_secret+params)));
newData["app_id"]=aid ;
newData["m_verified_way"]=4;
newData.timestamp=timestamp;
newData.v=v;
newData["msg_digest"]=msg_digest;
output={ts:timestamp,sign:msg_digest,'app_id':aid, v: v, params:params,newData:JSON.stringify(newData )};

2.2调用实名认证接口难道链接
var indata=JSON.parse(input.data);
var url=input.url+'/api/get_company_verify_url.api';
const fetch = require('node-fetch'); 
const FormData= require('form-data');
var result={};
let data= new FormData();

Object.keys(indata).forEach((key) => {
 data.append(key,indata[key]);
})
async function getAll(data){
    const res = await   fetch(url,{
    method:"post",
    body:data
}).then(function(response){
    if(response.ok){
 return  response.json();   
    }else{
  return   {"error":"无数据"};
}
}).catch(function(err){
   return   {"error":"Fetch错误:"+err};
});
    const result = await   res;
    return result;
}
result=await  getAll(data);
output={result:result}

拿到接口返回的链接,使用打开界面节点 打开新连接。认证成功后在你的信息接受地址中调用申请证书接口。

  1. 上传合同单个签署
    image.png
  • uploaddocs.api 合同上传接⼝
  • extsign_auto.api 自动签接⼝
代码块示例
1.合同上传参数加密
var crypto = require('crypto');
var doc_title='', doc_type='';
var v = input.v;
var app_secret = input.appsecret;
var aid = input.aid;
var contractid=input.contractid+'-'+parseInt(input.ind).toString();
var imgurl=input.imgurl
var types=['.doc','.docx','.pdf','.jpg','.jpeg','.png','.bmp']
//法大大不支持图片签章,e签宝支持.这里是为了后面方法公共
function getfiletype(f){
  var obj={'ftype':'','fname':''};
  for(var i=0;i<types.length;i++){
   var find=f.indexOf(types[i])
   var temp=f;
   if(find>-1){
      obj.ftype=types[i];
      temp=temp.substring(0,find);
      obj.fname=getfilename(find,temp);
      break;
    }
  }
  return obj;
}
function getfilename(find,f){
    var fname=''
    f=f.substring(0,find);
    var nind=f.lastIndexOf('/');
    if(nind>-1){
      fname=f.substring(nind+1,f.length);
    }else{
       nind=f.lastIndexOf('=');
       if(nind>-1){
       fname=f.substring(nind+1,f.length);
      }
    }
    return fname;
}
var obj=getfiletype(imgurl);
doc_type=obj.ftype;
doc_title=obj.fname;
var data={
"contract_id":contractid,
"doc_title":doc_title,
"doc_type":doc_type,
'doc_url':imgurl}

function pad2(n) { return n < 10 ? '0' + n : n }
function generateTimeReqestNumber() {
            var datee = new Date();
var localTime = datee .getTime();
var localOffset=datee .getTimezoneOffset()*60000; //获得当地时间偏移的毫秒数
var utc = localTime + localOffset; //utc即GMT时间
var offset =8; //以北京时间为例,东8区
var hawaii = utc + (3600000*offset); 
	var date = new Date(hawaii);
	date.setHours(date.getHours());
	return date.getFullYear().toString() + pad2(date.getMonth() + 1) + pad2(date.getDate()) + pad2(date.getHours()) + pad2(date.getMinutes()) + pad2(date.getSeconds());
}
function sha1(s) {
	var hash = crypto.createHash('sha1');
	hash.update(s);
	return hash.digest('hex').toUpperCase();
}
function md5(s) {
	var hash = crypto.createHash('md5');
	hash.update(s);
	return hash.digest('hex').toUpperCase();
}
function base64(s) {
	var b = new Buffer.from(s);
	return b.toString('base64');
}
function ast(s) {
	return s.split('').sort().join('');
}
var newData = {},params='';
Object.keys(data).sort().map(key => {
  newData[key]=data[key]
  params=params+=data[key];
})
var timestamp = generateTimeReqestNumber();	
var msg_digest = base64( sha1(aid + md5(timestamp) + sha1(app_secret+data.contract_id)));
newData["app_id"]=aid ;
newData.timestamp=timestamp;
newData.v=v;
newData["msg_digest"]=msg_digest;
output={ts:timestamp,sign:msg_digest,'app_id':aid, v: v, params:params,newData:JSON.stringify(newData),contractid:contractid,doc_title:doc_title};
1.1 合同上传
const fetch = require('node-fetch'); 
const FormData= require('form-data');

var indata=JSON.parse(input.data);
var url=input.url+'/api/uploaddocs.api';
var result={};
var tempparams='';
let data= new FormData();

Object.keys(indata).forEach((key) => {
 data.append(key,indata[key]);
})
async function getAll(data){
    const res = await   fetch(url,{
    method:"post",
    body:data
}).then(function(response){
    if(response.ok){
 return  response.json();   
    }else{
  return   {"error":"无数据"};
}
}).catch(function(err){
   return   {"error":"Fetch错误:"+err};
});
    const result = await   res;
    return result;
}
result=await  getAll(data);

output={result:result}

剩下接口调用几乎一样,请查看 API 接口调用,特别注意:每个接口的签名规则需要细看下。最后自动签署的流程,需要设置异步通知的地址,因为存在签署中的状态。根据异步通知中的接受到的数据在工作流设置签署后的文件。

客户使用案例【## 上海安畅网络科技股份有限公司】

总结

  务实的明道云,技术不断的在创新突破(🎉️ 率先支持 ARM64 服务器 🎉️ ),版本一致优质的迭代更新。(每月一版本 👍 ),,每次的更新迭代,带给您最美的期待。
(下篇 e 签宝对接案例,请持续关注明道云 🚀️ )

明道云
明道云 APaaS 平台率先支持 ARM64 服务器
法大大