我正在使用Docusign SOAP API亲自与多个收件人签名。一切正常,直到我想在我的身份验证中集成OpenTrust证书。这就是矛盾:
对于签约上班的人,收件人的RoutingOrder必须相同。否则您将收到以下肥皂错误: 无法生成无序收件人的令牌。
要使OpenTrust证书有效,RoutingOrder必须是不同的。否则您将收到以下错误: 指定RequireSignerCertificate时,同一路由顺序中不得有其他收件人。
如果我能找到一个与多个收件人和不同路由订单签约的解决方案,也许它可以解决问题。这是我的代码:
Map<string, Docusign_API__c> mcs = Docusign_API__c.getAll();
String accountId = mcs.get('accountId').Value__c;
String userId = '[' + UserInfo.getUserEmail() + ';' + UserInfo.getName() + ']' + mcs.get('userId').Value__c;
String password = mcs.get('password').Value__c;
String integratorsKey = mcs.get('integratorsKey').Value__c;
String webServiceUrl = mcs.get('webServiceUrl').Value__c;
string CarbonCopyEmail = mcs.get('bcc').Value__c;
string RecordId = 'a0411000006Ijy1';
string envelopeId = null;
DocuSignAPI.APIServiceSoap dsApiSend = new DocuSignAPI.APIServiceSoap();
dsApiSend.endpoint_x = webServiceUrl;
//Set Authentication
system.debug(userId);
String auth = '<DocuSignCredentials><Username>'+ userId
+'</Username><Password>' + password
+ '</Password><IntegratorKey>' + integratorsKey
+ '</IntegratorKey></DocuSignCredentials>';
System.debug('Setting authentication to: ' + auth);
dsApiSend.inputHttpHeaders_x = new Map<String, String>();
dsApiSend.inputHttpHeaders_x.put('X-DocuSign-Authentication', auth);
DocuSignAPI.Envelope envelope = new DocuSignAPI.Envelope();
envelope.Subject = 'Please Sign this Contract: ' + contract.ContractNumber;
envelope.EmailBlurb = 'This is my new eSignature service, it allows me to get your signoff without having to fax, scan, retype, refile and wait forever';
envelope.AccountId = accountId;
envelope.CustomFields = new DocuSignAPI.ArrayOfCustomField();
envelope.CustomFields.CustomField = new DocuSignAPI.CustomField[1];
DocuSignAPI.CustomField env_customfield = new DocuSignAPI.CustomField();
env_customfield.Name = 'DSFSSourceObjectId';
env_customfield.Show = 'false';
env_customfield.Required = 'true';
env_customfield.Value = RecordId +'~object__c';
env_customfield.CustomFieldType = 'Text';
env_customfield.ListItems = '';
envelope.CustomFields.CustomField[0] = env_customfield;
// Document
//Add Attachments
list<Attachment> listAttachments = [SELECT Id, Name, Body FROM Attachment WHERE ParentId = :RecordId];
envelope.Documents = new DocuSignAPI.ArrayOfDocument();
envelope.Documents.Document = new DocuSignAPI.Document[listAttachments.size()];
integer attCounter = 0;
for(Attachment att : listAttachments){
DocuSignAPI.Document document2 = new DocuSignAPI.Document();
document2.ID = attCounter;
document2.pdfBytes = EncodingUtil.base64Encode(att.Body);
document2.Name = att.Name;
if(att.Name.contains('.')){
document2.FileExtension = att.Name.split('\\.')[1];
}
envelope.Documents.Document[attCounter] = document2;
attCounter++;
}
envelope.Recipients = new DocuSignAPI.ArrayOfRecipient();
envelope.Recipients.Recipient = new DocuSignAPI.Recipient[2];
// Recipient 1
DocuSignAPI.Recipient recipient = new DocuSignAPI.Recipient();
recipient.ID = 1;
//recipient.RequireSignerCertificate = 'OpenTrust';
recipient.Type_x = 'InPersonSigner';
recipient.CaptiveInfo = new DocuSignAPI.RecipientCaptiveInfo();
recipient.CaptiveInfo.ClientUserId = '1';
recipient.RoleName = 'Signer 1';
recipient.RoutingOrder = 1;
recipient.Email = 'recipient1@test.com';
recipient.UserName = 'recipient1 test';
recipient.SignerName = 'recipient1 test';
recipient.RequireIDLookup = false;
envelope.Recipients.Recipient[0] = recipient;
//Recipient2
DocuSignAPI.Recipient recipient2 = new DocuSignAPI.Recipient();
recipient2.ID = 2;
//recipient2.RequireSignerCertificate = 'OpenTrust';
recipient2.Type_x = 'InPersonSigner';
recipient2.Email = 'recipient1@test.com';
recipient2.UserName = 'recipient1 test';
recipient2.SignerName = 'Person 2';
recipient2.CaptiveInfo = new DocuSignAPI.RecipientCaptiveInfo();
recipient2.CaptiveInfo.ClientUserId = '2';
recipient2.RoleName = 'Signer 2';
recipient2.RoutingOrder = 2;
envelope.Recipients.Recipient[1] = recipient2;
envelope.Tabs = new DocuSignAPI.ArrayOfTab();
envelope.Tabs.Tab = new DocuSignAPI.Tab[2];
// Tab - Apporteur
DocuSignAPI.Tab tab1 = new DocuSignAPI.Tab();
tab1.Type_x = 'SignHere';
tab1.RecipientID = 1;
tab1.DocumentID = 1;
tab1.AnchorTabItem = new DocuSignAPI.AnchorTab();
tab1.AnchorTabItem.AnchorTabString = 's1';
envelope.Tabs.Tab[0] = tab1;
// Tab - Souscripteur
DocuSignAPI.Tab tab2 = new DocuSignAPI.Tab();
tab2.Type_x = 'SignHere';
tab2.RecipientID = 2;
tab2.DocumentID = 1;
tab2.AnchorTabItem = new DocuSignAPI.AnchorTab();
tab2.AnchorTabItem.AnchorTabString = 's2';
envelope.Tabs.Tab[1] = tab2;
//I - Send Enveloppe
DocuSignAPI.EnvelopeStatus es = dsApiSend.CreateAndSendEnvelope(envelope);
envelopeId = es.EnvelopeID;
//II - Get Signing Toekn
Blob b = Crypto.GenerateAESKey(128);
String h = EncodingUtil.ConvertTohex(b);
String guid = h.SubString(0,8)+ '-' + h.SubString(8,12) + '-' + h.SubString(12,16) + '-' + h.SubString(16,20) + '-' + h.substring(20);
DocuSignAPI.RequestRecipientTokenAuthenticationAssertion assertion = new DocuSignAPI.RequestRecipientTokenAuthenticationAssertion();
assertion.AssertionID = guid;
assertion.AuthenticationInstant = DateTime.Now();
assertion.AuthenticationMethod = 'Email';
assertion.SecurityDomain = 'force.com';
// Construct the URLs based on username
DocuSignAPI.RequestRecipientTokenClientURLs urls = new DocuSignAPI.RequestRecipientTokenClientURLs();
String urlBase = URL.getSalesforceBaseUrl().toExternalForm()+'/'+RecordId;
urls.OnSigningComplete = urlBase + '?event=SignComplete&uname=' + recipient.UserName;
urls.OnViewingComplete = urlBase + '?event=ViewComplete&uname=' + recipient.UserName;
urls.OnCancel = urlBase + '?event=Cancel&uname=' + recipient.UserName;
urls.OnDecline = urlBase + '?event=Decline&uname=' + recipient.UserName;
urls.OnSessionTimeout = urlBase + '?event=Timeout&uname=' + recipient.UserName;
urls.OnTTLExpired = urlBase + '?event=TTLExpired&uname=' + recipient.UserName;
urls.OnIdCheckFailed = urlBase + '?event=IDCheck&uname=' + recipient.UserName;
urls.OnAccessCodeFailed = urlBase + '?event=AccessCode&uname=' + recipient.UserName;
urls.OnException = urlBase + '?event=Exception&uname=' + recipient.UserName;
//Request second person token
string RecipientToken = dsApiSend.RequestRecipientToken(
es.EnvelopeID,
recipient.CaptiveInfo.ClientUserId,
recipient.UserName,
recipient.Email,
assertion,
urls);
//Request second person token
string RecipientToken2 = dsApiSend.RequestRecipientToken(
es.EnvelopeID,
recipient2.CaptiveInfo.ClientUserId,
recipient2.UserName,
recipient2.Email,
assertion,
urls);
//Add the token of the second recipient in the Signing complete of the first
//urls.OnSigningComplete = RecipientToken2;
Pagereference tokenpage = new Pagereference(RecipientToken);
return tokenpage.setRedirect(true);
答案 0 :(得分:1)
核心要求(对于OpenTrust签名)是必须将收件人设置为顺序路由(例如,每个收件人的RoutingOrder 1和2)。在顺序路由中,一次只有一个收件人处于活动状态。签名者1签名后,他们被标记为完成,签名者2随后变为活动状态。
收件人只能在活动时签名。这也适用于获取收件人令牌。您只能为活跃的签名者获取令牌。
请注意,面对面签名实际上并不要求收件人处于相同的路由顺序中。
解决方案的关键是仅在第一个收件人签名后才请求第二个收件人令牌。第一个会话的登陆URL应指向VF页面 - 例如,可能将信封ID作为参数(或记录的对象ID)。然后,该VF页面的控制器将请求第二个签名者的收件人令牌,并重定向到该URL或将其作为IFrame中的源URL返回。