Я использую Docusign SOAP API для подписания подписей с несколькими получателями. Все работало нормально до тех пор, пока я не захотел интегрировать сертификат OpenTrust в свою аутентификацию. И вот это противоречие:Docusign SOAP API InPerson подписание с несколькими получателями и 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 = '[email protected]';
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 = '[email protected]';
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);
Почему вы не создаете конверт, генерируете токен получателя для получателя # 1 (который должен работать), когда этот человек выполнил свою часть, вы создаете токен получателя для получателя # 2. – Andrew