The Docusign REST API describes a way to control document visibility when creating envelopes from documents:
https://docs.docusign.com/esign/restapi/Envelopes/Envelopes/create/
The option is enforceSignerVisibility. However when I attempt to use this option, the visibility is NOT limited. Am I doing something wrong?
I am using a modified version of the PHP DocuSign helper library (some features/options added).
Here is a test case I created. In this case, there are two signers and two documents. Signer 1 has a signature on Document 1 and Signer 2 has a signature on Document 2. The goal is that Signer 1 would only see Document 1 and Signer 2 would only see Document 2. However, the below example results in both signers seeing both documents:
Code
<?php
$client = new DocuSign_Client;
$service = new DocuSign_RequestSignatureService($client);
$documents = array(
new DocuSign_Document(
"TestDoc1",
1,
file_get_contents( $_SERVER['DOCUMENT_ROOT'].'/sandbox/ncg/test1.pdf' )
),
new DocuSign_Document(
"TestDoc2",
2,
file_get_contents( $_SERVER['DOCUMENT_ROOT'].'/sandbox/ncg/test2.pdf' )
)
);
$signer1 = new DocuSign_Recipient(
1,
1,
"Signer 1",
"test.tfcornerstone+t1#gmail.com",
NULL
);
$signer1->setTab("signHereTabs",array(
"anchorYOffset" => "0",
"anchorXOffset" => "0",
"anchorString" => "[__[Signer1]__]",
"anchorIgnoreIfNotPresent" => true,
) );
$signer2 = new DocuSign_Recipient(
1,
2,
"Signer 2",
"test.tfcornerstone+t2#gmail.com",
NULL
);
$signer2->setTab("signHereTabs",array(
"anchorYOffset" => "0",
"anchorXOffset" => "0",
"anchorString" => "[__[Signer2]__]",
"anchorIgnoreIfNotPresent" => true,
) );
$recipients = array( $signer1, $signer2 );
$emailSubject = "Test Doc";
$emailBlurb = "Testing Visibility";
$status = 'sent'; // can be "created" or "sent"
$eventNotifications = new DocuSign_EventNotification(
$url, //url
false, //loggingEnabled
false, //requireAcknowledgment,
false, //useSoapInterface,
NULL, //soapNameSpace,
false, //includeCertificateWithSoap,
false, //signMessageWithX509Cert,
false, //includeDocuments,
false, //includeTimeZone,
false, //includeSenderAccountAsCustomField,
NULL, //envelopeEvents,
array( "Completed", "Sent" ) //recipientEvents
);
$options = array(
"enforceSignerVisibility" => true,
);
$response = $service->signature->createEnvelopeFromDocument(
$emailSubject,
$emailBlurb,
$status,
$documents,
$recipients,
$eventNotifications,
$options
);
d($response);
CURL request
Url: https://www.docusign.net/restapi/v2/accounts/XXXXX/envelopes
Method: POST
Headers:
--myboundary
Content-Type: application/json
Content-Disposition: form-data
{"emailSubject":"Test Doc","emailBlurb":"Testing Visibility","documents":[{"name":"TestDoc1","documentId":1},{"name":"TestDoc2","documentId":2}],"status":"sent","enforceSignerVisibility":true,"recipients":{"signers":[{"routingOrder":1,"recipientId":1,"name":"Signer 1","email":"test.tfcornerstone+t1#gmail.com","clientUserId":null,"tabs":{"signHereTabs":[{"anchorYOffset":"0","anchorXOffset":"0","anchorString":"[__[Signer1]__]","anchorIgnoreIfNotPresent":true}]},"embeddedRecipientStartUrl":null,"excludedDocuments":null},{"routingOrder":1,"recipientId":2,"name":"Signer 2","email":"test.tfcornerstone+t2#gmail.com","clientUserId":null,"tabs":{"signHereTabs":[{"anchorYOffset":"0","anchorXOffset":"0","anchorString":"[__[Signer2]__]","anchorIgnoreIfNotPresent":true}]},"embeddedRecipientStartUrl":null,"excludedDocuments":null}]},"eventNotification":{"loggingEnabled":false,"requireAcknowledgment":false,"useSoapInterface":false,"includeCertificateWithSoap":false,"signMessageWithX509Cert":false,"includeDocuments":false,"includeTimeZone":false,"includeSenderAccountAsCustomField":false,"recipientEvents":[{"recipientEventStatusCode":"Completed"},{"recipientEventStatusCode":"Sent"}]}}
<<PDF CONTENT>>--myboundary--
Formatted JSON data
{
"emailSubject": "Test Doc",
"emailBlurb": "Testing Visibility",
"documents": [
{
"name": "TestDoc1",
"documentId": 1
},
{
"name": "TestDoc2",
"documentId": 2
}
],
"status": "sent",
"enforceSignerVisibility": true,
"recipients": {
"signers": [
{
"routingOrder": 1,
"recipientId": 1,
"name": "Signer 1",
"email": "test.tfcornerstone+t1#gmail.com",
"clientUserId": null,
"tabs": {
"signHereTabs": [
{
"anchorYOffset": "0",
"anchorXOffset": "0",
"anchorString": "[__[Signer1]__]",
"anchorIgnoreIfNotPresent": true
}
]
},
"embeddedRecipientStartUrl": null,
"excludedDocuments": null
},
{
"routingOrder": 1,
"recipientId": 2,
"name": "Signer 2",
"email": "test.tfcornerstone+t2#gmail.com",
"clientUserId": null,
"tabs": {
"signHereTabs": [
{
"anchorYOffset": "0",
"anchorXOffset": "0",
"anchorString": "[__[Signer2]__]",
"anchorIgnoreIfNotPresent": true
}
]
},
"embeddedRecipientStartUrl": null,
"excludedDocuments": null
}
]
},
"eventNotification": {
"loggingEnabled": false,
"requireAcknowledgment": false,
"useSoapInterface": false,
"includeCertificateWithSoap": false,
"signMessageWithX509Cert": false,
"includeDocuments": false,
"includeTimeZone": false,
"includeSenderAccountAsCustomField": false,
"recipientEvents": [
{
"recipientEventStatusCode": "Completed"
},
{
"recipientEventStatusCode": "Sent"
}
]
}
}
I don't believe DocVis can be set to "Off" in order to enforce it in the API. In Preferences -> Features change the DocVis dropdown to "Sender Can Set Must Sign To View Unless Sender Account" and give the same request another shot.
Related
I am trying to sync DocuSign info and I want to track some envelope statuses and some recipient statuses.
I am using such data for draft envelope:
{
"emailSubject": "test 1",
"emailBlurb": null,
"recipients": null,
"documents": [
{
"documentId": 1,
"name": "DocuSign_current_sync.pdf",
"documentBase64": ".....",
"fileExtension": "pdf"
}
],
"status": "created",
"eventNotification": {
"url": "https://webhook.site/{id}",
"requireAcknowledgment": true,
"includeDocuments": false,
"includeEnvelopeVoidReason": true,
"includeSenderAccountAsCustomField": false,
"loggingEnabled": true,
"envelopeEvents": [
{
"envelopeEventStatusCode": "sent",
"includeDocuments": false
},
{
"envelopeEventStatusCode": "delivered",
"includeDocuments": false
},
{
"envelopeEventStatusCode": "declined",
"includeDocuments": false
},
{
"envelopeEventStatusCode": "voided",
"includeDocuments": false
},
{
"envelopeEventStatusCode": "completed",
"includeDocuments": false
}
],
"recipientEvents": [
{
"recipientEventStatusCode ": "signed",
"includeDocuments": false
},
{
"recipientEventStatusCode ": "completed",
"includeDocuments": false
}
],
"eventData": {
"format": "json",
"version": "restv2.1",
"includeData": [
"recipients"
]
}
}}
I am expecting to receive notification envelope status changes and notification each time when the recipient has signed/completed his process
But I am receiving only envelope level notifications and do not get any updates in a case when the recipient change his status
Any thoughts on what is wrong and how I can fix that?
Going to guess the issue is the extra space. I would expect an error message for an invalid recipient. Going to check into this.
"recipientEventStatusCode ": "signed",
Should be:
"recipientEventStatusCode": "signed",
I'm getting an error when finishing a DocuSign Ceremony using EU Advanced Signature with Templates. The odd thing is that it was working before and still working for ceremonies that have an embedded PDF.
When finishing a ceremony the following error is popping up:
The envelope history shows more details:
It mentions the userEmail, so I've double-checked the JSON and everything seems to be fine, after all, I didn't get any error when creating the envelope.
Here's the JSON using a Template that is failing:
{
"status": "sent",
"eventNotification": {
"recipientEvents": [
{
"recipientEventStatusCode": "delivered"
},
{
"recipientEventStatusCode": "completed"
},
{
"recipientEventStatusCode": "sent"
},
{
"recipientEventStatusCode": "declined"
}
],
"envelopeEvents": [
{
"envelopeEventStatusCode": "delivered"
},
{
"envelopeEventStatusCode": "completed"
},
{
"envelopeEventStatusCode": "sent"
},
{
"envelopeEventStatusCode": "declined"
}
]
},
"emailSubject": "Contract",
"compositeTemplates": [
{
"serverTemplates": [
{
"templateId": "TEMPLATE_ID",
"sequence": "1"
}
],
"inlineTemplates": [
{
"sequence": "1",
"recipients": {
"signers": [
{
"routingOrder": "2",
"roleName": "Signer 2",
"recipientSignatureProviders": [
{
"signatureProviderOptions": {
"sms": "+00999555585"
},
"signatureProviderName": "UniversalSignaturePen_OpenTrust_Hash_TSP"
}
],
"recipientId": "2",
"name": "Axel Foley",
"emailNotification": {
"supportedLanguage": "en",
"emailSubject": "CUSTOM_MESSAGE",
"emailBody": "CUSTOM_MESSAGE"
},
"email": " axel.foley#email.com"
},
{
"routingOrder": "2",
"roleName": "Signer 3",
"recipientSignatureProviders": [
{
"signatureProviderOptions": {
"sms": "+00123456789"
},
"signatureProviderName": "UniversalSignaturePen_OpenTrust_Hash_TSP"
}
],
"recipientId": "3",
"name": "Alex Murphy",
"emailNotification": {
"supportedLanguage": "en",
"emailSubject": "CUSTOM_MESSAGE",
"emailBody": "CUSTOM_MESSAGE"
},
"email": "alex.murphy#email.com"
}
],
"inPersonSigners": [
{
"signerName": "Leeroy Jenkins",
"signerEmail": "leeroy.jenkins#email.com",
"routingOrder": "1",
"roleName": "Signer 1",
"recipientSignatureProviders": [
{
"signatureProviderOptions": {
"sms": "+00666888777"
},
"signatureProviderName": "UniversalSignaturePen_OpenTrust_Hash_TSP"
}
],
"recipientId": "1",
"hostName": "Lightning McQueen",
"hostEmail": "lightning.mcqueen#email.com",
"emailNotification": {
"supportedLanguage": "en",
"emailSubject": "CUSTOM_MESSAGE",
"emailBody": "CUSTOM_MESSAGE"
},
"clientUserId": "SFDC_CLIENT_USER_ID"
}
]
},
"customFields": {
"textCustomFields": [
{
"value": "SFDC_ID",
"show": "false",
"required": "false",
"name": "##SFContract"
}
]
}
}
]
}
]
}
And here's the JSON with an embedded PDF that works fine:
{
"status": "sent",
"recipients": {
"inPersonSigners": [
{
"tabs": {
"signHereTabs": [
{
"anchorYOffset": "0",
"anchorXOffset": "0",
"anchorUnits": "inches",
"anchorString": "\\s1\\",
"anchorIgnoreIfNotPresent": "false"
}
]
},
"signerName": "Vincent Vega",
"signerEmail": "vicent.vega#email.com",
"routingOrder": "1",
"roleName": "Signer 1",
"recipientSignatureProviders": [
{
"signatureProviderOptions": {
"sms": "+00789456123"
},
"signatureProviderName": "UniversalSignaturePen_OpenTrust_Hash_TSP"
}
],
"recipientId": "1",
"hostName": "Lightning McQueen",
"hostEmail": "lightning.mcqueen#email.com",
"emailNotification": {
"supportedLanguage": "en",
"emailSubject": "CUSTOM_MESSAGE",
"emailBody": "CUSTOM_MESSAGE"
},
"clientUserId": "SFDC_CLIENT_USER_ID"
}
]
},
"eventNotification": {
"recipientEvents": [
{
"recipientEventStatusCode": "delivered"
},
{
"recipientEventStatusCode": "completed"
},
{
"recipientEventStatusCode": "sent"
},
{
"recipientEventStatusCode": "declined"
}
],
"envelopeEvents": [
{
"envelopeEventStatusCode": "delivered"
},
{
"envelopeEventStatusCode": "completed"
},
{
"envelopeEventStatusCode": "sent"
},
{
"envelopeEventStatusCode": "declined"
}
]
},
"documents": [
{
"name": "Form.pdf",
"fileExtension": "pdf",
"documentId": "1",
"documentBase64": "BASE64_PDF"
}
],
"customFields": {
"textCustomFields": [
{
"value": "SFDC_ID",
"show": "false",
"required": "false",
"name": "##SFAccount"
}
]
}
}
Am I missing something? Have anyone ever seen this error before?
It's worth to mention that I'm getting the error right in the first signature (InPerson).
Kind regards
It turned out that is a known issue of DocuSign.
There is a known issue during an in-person signing session when the signer clicks on Finished, he should get the following popup
If you don’t set any email, it will fail with the CONSTRAINT_VALIDATION_ERROR
The workaround is to specify an email.
I am trying to convert form fields with name signature_1 and pre-filled value of signature_1.
I have been following this guide:
https://www.docusign.com/developer-center/explore/features/stick-etabs
Here is the issue that i have already written up on the problem: https://github.com/karmaradio/karma/issues/440
Docusign is creating signHere tabs on the contract, but always at the top left, so it isn't recognising the signature_1 form field.
The object i send to docusign:
{
emailBlurb: "Please sign the document using link provided.",
emailSubject: "Karma document sign",
documents: [
{
documentBase64: "encoded",
documentId: 1,
name: "jackum-mur-PAYE-1.pdf",
transformPdfFields: "true"
}
],
recipients: {
signers: [
{
email: "jmurphy+c#gmail.com",
name: "jackum mur",
recipientId: 1,
routingOrder: 1,
tabs: {
signHereTabs: [
{
documentId: "1",
pageNumber: "1",
tabLabel: "signature_1"
}
]
}
},
{
email: "jmurphy+first#gmail.com",
name: "first signee",
recipientId: 2,
routingOrder: 2,
tabs: {
signHereTabs: [
{
documentId: "1",
pageNumber: "1",
tabLabel: "signature_2"
}
]
}
},
{
email: "jmurphy+second#gmail.com",
name: "second signee",
recipientId: 3,
routingOrder: 3,
tabs: {
signHereTabs: [
{
documentId: "1",
pageNumber: "1",
tabLabel: "signature_3"
}
]
}
},
status: "sent"
}
After examining the document you have shared, the following json should covert the form fields appropriately. Looking at the convention of your Tab labels, it is not clear which tabs apply to a particular recipient. So I have manually mapped each tabLabel to a recipient. From my example you can move the tabs based on the correct recipient.
If you want similar tab types to automatically populate with the same data then see here
Here is the CreateEnvelope request.
POST /v2/accounts/{accountId}/envelopes
{
"emailSubject": "Document with Form fields",
"status": "sent",
"compositeTemplates": [
{
"document": {
"documentBase64": "<Add the bas64 encoded document bytes here>",
"documentId": "1",
"name": "p60-form.pdf",
"transformPdfFields": "true"
},
"inlineTemplates": [
{
"sequence": "1",
"recipients": {
"signers": [
{
"email": "jmurphy+c#gmail.com",
"name": "jackum mur",
"recipientId": "1",
"routingOrder": "1",
"tabs": {
"signHereTabs": [
{
"tabLabel": "signature_1"
},
{
"tabLabel": "signature_1DocuSignSignHere"
}
],
"textTabs": [
{
"tabLabel": "signature_1 Student Loan deductions",
"value" : "<Pre-Fill Tab Value here>"
},
{
"tabLabel": "Student Loan deductions",
"value" : "<Pre-Fill Tab Value here>"
},
{
"tabLabel": "PAYE reference",
"value" : "<Pre-Fill Tab Value here>"
},
{
"tabLabel": "Your employer's full name and address (including postcode",
"value" : "<Pre-Fill Tab Value here>"
}
]
}
},
{
"email": "jmurphy+first#gmail.com",
"name": "first signee",
"recipientId": "2",
"routingOrder": "2",
"tabs": {
"signHereTabs": [
{
"tabLabel": "signature_2"
},
{
"tabLabel": "signature_2 DocuSignSignHere"
}
],
"textTabs": [
{
"tabLabel": "signature_2",
"value" : "<Pre-Fill Tab Value here>"
},
{
"tabLabel": "signature_2 Your employers full name and address including postcode",
"value" : "<Pre-Fill Tab Value here>"
}
]
}
},
{
"email": "jmurphy+second#gmail.com",
"name": "second signee",
"recipientId": "3",
"routingOrder": "3",
"tabs": {
"signHereTabs": [
{
"tabLabel": "signature_3"
},
{
"tabLabel": "signature_3 DocuSignSignHere"
}
],
"textTabs": [
{
"tabLabel": "signature_3 PAYE reference",
"value" : "<Pre-Fill Tab Value here>"
}
]
}
}
]
}
}
]
}
]
}
I'm working on a DocuSign integration. I have the basics functional but can't seem to figure out how to merge a local document (PDF) with a server template such that tabs configured on the server template get used or overlaid on the passed document.
My template is defined on the server and I can use it directly from the web UI without issue (it's a W4 form). The template has three tabs (SSN, Sign here, and date) as you can see below. Accessing this template via it's ID using the API Explorer yields the following json
{
"envelopeTemplateDefinition": {
"templateId": "_redacted_",
"name": "W4 3/13/2017",
"shared": "true",
"password": "",
"description": "",
"lastModified": "2017-06-05T18:45:28.4470000Z",
"lastModifiedBy": {
"userName": "Andrew",
"userId": "_redacted_",
"email": "my_email_address",
"uri": "/users/_redacted_
},
"pageCount": 2,
"uri": "/templates/_redacted_",
"folderName": "Templates",
"folderId": "_redacted_",
"folderUri": "/folders/_redacted_",
"owner": {
"userName": "Andrew",
"userId": "_redacted_",
"email": "my_email_address"
}
},
"documents": [
{
"documentId": "46677269",
"uri": "/envelopes/_redacted_/documents/46677269",
"name": "W4.pdf",
"order": "1",
"pages": "2",
"display": "inline",
"includeInDownload": "true",
"signerMustAcknowledge": "no_interaction",
"templateLocked": "false",
"templateRequired": "false",
"documentGroup": "content"
}
],
"emailSubject": "Please DocuSign: W4.pdf",
"emailBlurb": "",
"signingLocation": "online",
"autoNavigation": "true",
"envelopeIdStamping": "true",
"authoritativeCopy": "false",
"notification": {
"reminders": {
"reminderEnabled": "false",
"reminderDelay": "0",
"reminderFrequency": "0"
},
"expirations": {
"expireEnabled": "true",
"expireAfter": "120",
"expireWarn": "0"
}
},
"enforceSignerVisibility": "false",
"enableWetSign": "true",
"allowMarkup": "false",
"allowReassign": "true",
"recipients": {
"signers": [
{
"defaultRecipient": "false",
"tabs": {
"signHereTabs": [
{
"stampType": "signature",
"name": "SignHere",
"tabLabel": "Signature _redacted_",
"scaleValue": 1.0,
"optional": "false",
"documentId": "46677269",
"recipientId": "94043042",
"pageNumber": "1",
"xPosition": "193",
"yPosition": "682",
"tabId": "_redacted_",
"templateLocked": "false",
"templateRequired": "false"
}
],
"dateSignedTabs": [
{
"name": "DateSigned",
"value": "",
"tabLabel": "Date Signed _redacted_",
"font": "lucidaconsole",
"fontColor": "black",
"fontSize": "size9",
"documentId": "46677269",
"recipientId": "94043042",
"pageNumber": "1",
"xPosition": "480",
"yPosition": "713",
"tabId": "_redacted_",
"templateLocked": "false",
"templateRequired": "false"
}
],
"ssnTabs": [
{
"validationPattern": "",
"validationMessage": "",
"shared": "false",
"requireInitialOnSharedChange": "false",
"requireAll": "false",
"value": "",
"width": 144,
"required": "true",
"locked": "false",
"concealValueOnDocument": "true",
"disableAutoSize": "false",
"maxLength": 4000,
"tabLabel": "Text _redacted_",
"font": "lucidaconsole",
"fontColor": "black",
"fontSize": "size9",
"documentId": "46677269",
"recipientId": "94043042",
"pageNumber": "1",
"xPosition": "442",
"yPosition": "563",
"tabId": "_redacted_",
"templateLocked": "false",
"templateRequired": "false"
}
]
},
"signInEachLocation": "false",
"name": "",
"email": "",
"recipientId": "94043042",
"accessCode": "",
"requireIdLookup": "false",
"routingOrder": "1",
"note": "",
"roleName": "New Employee",
"deliveryMethod": "email",
"templateLocked": "false",
"templateRequired": "false",
"inheritEmailNotificationConfiguration": "false"
}
],
"agents": [ ],
"editors": [ ],
"intermediaries": [ ],
"carbonCopies": [ ],
"certifiedDeliveries": [ ],
"inPersonSigners": [ ],
"recipientCount": "1"
}
}
What I want to do is apply this template to a PDF that's already partially filled out such that when the signer get's it the tabs defined in the server template are used for the sining.
As it stands now, there's nothing. Just the partially filled out PDF I passed in below as base64 data, with none of the server template tabs to fill out or sign. Here's my json for the API call (in PHP).
$data = array (
"emailBlurb" => "Test Email Body",
"emailSubject" => "Test Email Subject",
"status" => "sent",
"compositeTemplates" => array(array(
"document" => array(
"documentId" => 46677269,
"name" => $documentName,
"documentBase64" => $document
),
"serverTemplates" => array(array(
"sequence" => 1,
"templateId" => "_redacted_"
)),
"inlineTemplates" => array(array(
"sequence" => 2,
"recipients" => array(
"signers" => array(array(
"email" => $recipientEmail,
"name" => $recipientName,
"recipientId" => $recipientID,
"roleName" => "New Employee"
))
)
))
))
); //$data = array...
I suspect that I'm simply missing some appropriate reference to the tabs defined in the server template. But documentation is atrocious and I've already spent several hours combing the web. Any help would be much appreciated.
UPDATE1
As requested, here's the code that generates the envelope successfully:
function c_requestSignature($templateID, $recipientName, $recipientEmail, $recipientID, $document){
//function sets up the passed document for signing using the specified template
$documentName = "W4"; //FIXME fetch document name using templateID
$baseURL = c_docusignBaseURL();
$accountId = c_docusignAccountId();
$header = c_docusignHeader();
$data = array (
"emailSubject" => "Please sign " . $documentName,
//"emailBlurb" => "Test Email Body",
"status" => "sent",
"compositeTemplates" => array(
"compositeTemplate" => array(
"serverTemplates" => array(
"serverTemplate" => array(
"sequence" => "1",
"templateId" => "_redacted_"
)
),
"inlineTemplates" => array(
"inlineTemplate" => array(
"sequence" => "2",
"recipients" => array(
"signers" => array(
"signer" => array(
"name" => $recipientName,
"email" => $recipientEmail,
"roleName" => "NewHire"
)
)
)
)
),
"document" => array(
"documentId" => "1",
"name" => $documentName,
"fileExtension" => "pdf",
"documentBase64" => $document
)
)
)
);
// Send to the /envelopes end point, which is relative to the baseUrl received above.
$curl = curl_init($baseURL . "/envelopes" );
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string),
"X-DocuSign-Authentication: $header" )
);
$json_response = curl_exec($curl); // Do it!
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 201 ) {
echo "Error calling DocuSign, status is:" . $status . "\nerror text: ";
print_r($json_response); echo "\n";
exit(-1);
}
$response = json_decode($json_response, true);
$envelopeId = $response["envelopeId"];
error_log ("successfully created envelope: $envelopeId");
$url = getSignatureURL($envelopeId, $recipientName, $recipientEmail, $recipientID);
return $url;
}//c_requestSignature()...
The function getSignatureURL() has code as follows:
function getSignatureURL($envelopeId, $recipientName, $recipientEmail, $recipientID){
//function retrieves the signing ceremony UX URL from DocuSign
$baseURL = c_docusignBaseURL();
$accountId = c_docusignAccountId();
$header = c_docusignHeader();
//set up the data we'll send to the Docusign server
$data = array("returnUrl" => "http://_redacted_",
"authenticationMethod" => "none",
"email" => $recipientEmail,
"name" => $recipientName,
"recipientId" => $recipientID,
//"recipientId" => "1",
//"clientUserId" => $recipientID,
"userName" => $recipientName
);
$data_string = json_encode($data);
//set up curl
$curl = curl_init($baseURL . "/envelopes/$envelopeId/views/recipient" );
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string),
"X-DocuSign-Authentication: $header" )
);
//make the API call
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 201 ) {
echo "error calling webservice, status is:" . $status . "\nerror text is --> ";
print_r($json_response); echo "\n";
exit(-1);
}
//retrieve and process the response
$response = json_decode($json_response, true);
return $response["url"];
}
UPDATE 2
Here's the raw json as requested...
{
"emailSubject": "some subject",
"status": "sent",
"compositeTemplates": [
{
"serverTemplates": [
{
"sequence": "1",
"templateId": "_redacted_"
}
],
"inlineTemplates": [
{
"sequence": "2",
"recipients": {
"signers": [
{
"name": "Andrew Tester1",
"email": "my_email_address",
"roleName": "NewHire",
"recipientId": "1234",
"clientUserId": "1234"
}
]
}
}
],
"document": {
"documentId": "1",
"name": "W4",
"fileExtension": "pdf",
"documentBase64": "_redacted_"
}
}
]
}
Update 3
I had a problem which was preventing me from seeing the proper output of the above json. With that fixed, now I'm getting the following error:
Error calling DocuSign, status is:400 error text: { "errorCode":
"TAB_REFERS_TO_MISSING_DOCUMENT", "message": "The DocumentId specified
in the tab element does not refer to a document in this envelope. Tab
refers to DocumentId 46677269 which is not present." }
If I change the document stanza above as follows:
"document": {
"documentId": "46677269",
"name": "W4",
"fileExtension": "pdf",
"documentBase64": "_redacted_"
}
The error goes away, but I still get a signing ceremony with no tabs.
The following request can be used to create an envelope from the Server Template. The server templates document will be replaced with the new document that is specified in the request.
{
"emailSubject": "Test Email Subject",
"emailBlurb" : "Test Email Body",
"status": "sent",
"compositeTemplates": [
{
"serverTemplates": [
{
"sequence": "1",
"templateId": "86841739-f12d-460e-9807-23a9b90cff6b"
}
],
"inlineTemplates": [
{
"sequence": "1",
"recipients": {
"signers": [
{
"name": "Jane Doe",
"email": "janedoe#acme.com",
"roleName": "New Employee"
}
]
}
}
],
"document": {
"documentId": "1",
"name": "Your Doc Name",
"fileExtension": "pdf",
"documentBase64": ""
}
}
]
}
Well this was a thorny problem, but I found the solution (finally), with some help form the folk at Docusign. I thought I'd post it here for those who might run into this in the future.
Solution
The json structure passed to the DocuSign API is extremely important. If there are any errors in it at all, it won't work right, and the error message is not always helpful. Furthermore, in what I was doing, the specific parameters passed were also crucial. The envelope generation code above is correct, though with the caveat that you must specify the PDF document ID that is part of the template stored on DocuSign's servers. You can query this via their API given the envelope ID (which is what I'm doing). Apparently this didn't use to be required, but now it is and there's no documentation anywhere stating that.
My fundamental problem with the signature tabs though, was the code requesting the signing ceremony URL. I had extra parameters which were being accepted without error, but were messing things up. Discovered this, by using DocuSign's REST API explorer to generate a working signing ceremony URL (complete with all the proper signature tabs), and comparing the output json whith what I was trying to pass in my code.
Here's the working PHP code that generates the correct json:
$data = array(
"authenticationMethod" => "email",
"clientUserId" => $recipientID,
"email" => $recipientEmail,
"returnUrl" => "_redacted_",
"userName" => $recipientName
);
$data_string = json_encode($data);
This is thru the Docusign api. Here is the envelope definition:
{
"eventNotification": {
"requireAcknowledgment": "true",
"envelopeEvents": [
{
"envelopeEventStatusCode": "Delivered"
},
{
"envelopeEventStatusCode": "Completed"
},
{
"envelopeEventStatusCode": "Declined"
},
{
"envelopeEventStatusCode": "Voided"
},
{
"envelopeEventStatusCode": "Sent"
}
],
"useSoapInterface": "false",
"includeCertificateWithSoap": "false",
"signMessageWithX509Cert": "false",
"includeDocuments": "false",
"includeEnvelopeVoidReason": "false",
"includeTimeZone": "true",
"includeSenderAccountAsCustomField": "true",
"includeDocumentFields": "true",
"includeCertificateOfCompletion": "false"
},
"compositeTemplates": [
{
"serverTemplates": [
{
"sequence": "1",
"templateId": "c110d14a-3690-4ed1-921d-a7bef9524ed6"
}
],
"inlineTemplates": [
{
"sequence": "2",
"recipients": {
"signers": [
{
"name": "Kathy Lori",
"email": "kathylori#xxx.com",
"recipientId": "1",
"accessCode": "12345",
"customFields": [],
"routingOrder": "1",
"note": "",
"roleName": "##Buyer1"
}
],
"certifiedDeliveries": []
},
"customFields": {
"textCustomFields": [
{
"name": "EnvelopeInfo",
"value": "my data"
}
]
}
}
],
"document": {
"documentId": "1",
"name": "c:\three of the test.docx",
"fileExtension": ".docx",
"documentFields": [],
"documentBase64": [bytearray]
}
}
],
"status": "sent",
"emailSubject": "This is the new subject"
}
The subject still shows as "Please DocuSign: sign this". I would have thought setting the subject would have addressed this, but I must be missing something.
You have most likely configured per recipient email subject in your server template. In such a case the emailSubject that is specified at the root level of the postEnvelope request is ignored.
You can confirm that by making a getTemplates call using your server template Id. It will look something like below. Look specifically for recipients.signers.emailNotification property. I have removed some of the properties for simplicity.
{
"envelopeTemplateDefinition": {
"templateId": "xxxxxxxx-xxxx-xxxx-xxxx-e672c4efd436",
},
"documents": [ ],
"emailSubject": "This is the subject on the server template.",
"emailBlurb": "",
"recipients": {
"signers": [
{
"tabs": {},
"roleName": "RoleOne",
"emailNotification": {
"emailSubject": "Please DocuSign: sign this",
"emailBody": "",
"supportedLanguage": "en"
},
}
]
}
}
To override the per recipient email subject specified in the server template, specify the emailNotification property in the inlineTemplate.
{
"compositeTemplates": [
{
"serverTemplates": [
{
"sequence": "1",
"templateId": "c110d14a-3690-4ed1-921d-a7bef9524ed6"
}
],
"inlineTemplates": [
{
"sequence": "2",
"recipients": {
"signers": [
{
"name": "Kathy Lori",
"email": "kathylori#xxx.com",
"recipientId": "1",
"accessCode": "12345"
"routingOrder": "1",
"roleName": "##Buyer1",
"emailNotification": {
"emailSubject": "This is email subject to Buyer1",
"emailBody": "",
"supportedLanguage": "en"
},
}
],
}
}
],
"document": { }
}
],
"status": "sent",
}