Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (5) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Implementing an NDA Signing iPad Application Using and the DocuSign API

Implementing an NDA Signing iPad Application Using and the DocuSign API

Post by Craig Smith  (2011-03-09)

Status: Unverified
Level: advanced


Your visitors must sign an NDA at your front desk. You want to streamline this process, making your visitor's first impression of your company memorable, and capture information about your visitor in


Use the Docusign API, Visualforce pages, and a Custom Object to have your visitor sign-in and sign an NDA document using an iPad!

Before getting started, you need to get a free Developer Edition account at, and a free DocuSign developer account at

The resultant application, running on an iPad, will look something like this:

  1. Start out by adding DocuSign web services to your authorized endpoints for your Developer Edition account. To do this, go to Setup->Security Controls->Remote Site Settings. Click on the New Remote Site button. Type in "DocuSignDemo" for the Remote Site Name and for the Remote Site URL and make sure the Active check box is checked. Click on Save. This URL will be your endpoint for DocuSign web service calls.
  2. Create a custom object. This object will be used to store your visitor's information. Start by going to Setup->Create->Objects. Click on the New Custom Object button. Fill in the Label textbox with "NDA Signer", Plural Label: NDA Signers, check Starts with vowel sound, Object Name: "NDA_Signer", Description: "Contains data for an NDA Signer", Record Name: "NDA Signer Name", Data Type: Text. Leave everything else at default and click Save. You'll see a detail of the NDA_Signer custom object with the following at the top:
  3. Create the Custom Fields & Relationships.
    1. Click on the New button.
      • Step 1: Select the "Text" radio button, then click Next.
      • Step 2: Type "here to see" for the Field Label. Type "128" for the Length and make sure the Field Name is "Here_to_see". Click the Required checkbox. Click Next.
      • Step 3: All of the Visible checkboxes should be checked. Click Next.
      • Step 4: The Add Field checkbox should be checked. Click Save & New.
    2. Create another text field doing the steps above for the Field Label "Selected name" with a Field Name of "Selected_name".
    3. Create another text field doing the steps above for the Field Label "Company" with a Field Name of "Company".
    4. Create a new email field.
      • Step 1: Email data type. Click Next.
      • Step 2: Field Label is "Email", Field Name is "Email", check Required checkbox. Click Next.
      • Step 3: accept defaults. Click Next.
      • Step 4: accept defaults. Click Save and New.
    5. Create a Purpose of Visit picklist field.
      • Step 1: Picklist data type. Click Next.
      • Step 2: Field Label is "Purpose of Visit", list of values is "Business", "Interview", "Personal", Check Use first value as default value, Field Name is "Purpose_of_Visit", leave rest at defaults. Click Next.
      • Step 3: Check Visible. Click Next.
      • Step 4: Check NDA_Signer Layout. Click Save and New.
    6. Create a Validate Method field
      • Step 1: Picklist data type. Click Next.
      • Step 2: Field Label is "Validate method", list of values is "SHOWID", "PHONE", "RSAID", check Use first value as default value, Field name is "Validate_method". Click Next.
      • Step 3: Check Visible. Click Next.
      • Step 4: Check NDA_Signer Layout. Click Save.

      The Custom Fields and Relationships area of the NDA_Signer Custom Object detail should look like:

  4. Create the proxy classes used to make DocuSign API calls. There are three classes we must create, all from DocuSign WSDLs. Download the following WSDLs and save them to your desktop:

    Now, go to Setup->Develop->Apex Classes and click on the Generate from WSDL button. Browse for the dsapi-send.wsdl.xml file you saved to your desktop and click the Parse WSDL button. Type "DocuSignAPI" for the Apex Class Name instead of the default and click on the Generate Apex code button.

    Do the same for dsapi-document.wsdl.xml calling it "DocuSignAPI_document".

    Do the same for dsapi-account.wsdl.xml calling it "DocuSignAPI_account".

  6. Upload a static resource file to provide some styling. Download the file in the Resources below. Go back you your Salesforce page, go to Setup->Develop->Static Resources. Click the New button. Type "ndaStyles" in the Name textbox. Browse for the file you just downloaded. Select Public for the Cache Control and click Save.
    The other two files in the staticresources dir is a ndastyles.css file that is the stylesheet that contains the branding styles, and an icon_ipad.png file that tells the iPad Safari browser what icon to use when this application is bookmarked to the iPad Home Page. You can change this, zip it to a new file, and upload it again to change the look of the NDAKiosk application.
  7. Create the Apex controller class that is used by the application. Go to Setup->Develop->Apex Classes and click on the New button. Download and unzip the file from the Resources below. Copy the text from the NDAKioskController.cls file and paste it into the class editor box.

    Click Quick Save. You will receive an error that says: Error: Page ndadone does not exist. Click the Create Page ndadone link. Click the Quick Save button again and you will receive a new error for the ndapop page. Click the Create Page link again. Repeat these two steps for the ndanameres, ndanotifyreception, ndaesign, and ndawelcome pages. Clicking the Quick Save button after creating the ndawelcome page should not result in any errors. Click the Save button.

  8. Now you'll add the code for these six pages. Download the file from the Resources below. Unzip the downloaded file. In your Salesforce site, go to Setup->Develop->Pages. Click the N link above the list to shorten it. You should see the six pages that were created in step 7. Click the Edit link for each page, and completely replace the code in the VisualForce Markup area with the code in the corresponding .page file that you unzipped for the downloaded file (e.g., replace all of the code for the VisualForce ndadone page with the text in the file).
  9. We're almost there! You must upload a template to your DocuSign account and get some information that will allow the NDAKioskController class to call your account and create NDA documents from your template. Download the file from the Resources below and unzip it. Login to your DocuSign dev account. Select the Templates folder on the left of the Console. Click the Browse button next to the Upload Template textbox and upload the xml template file you unzipped earlier. Click on the DocuSign Visitor NDA template then click on the Open link above. You will see something like the following at the top of the template:

    Note the string after the Template ID. This will need to be pasted into the NDAKioskController class created in step 7. Click the red X in the upper right-hand corner and click No when the Save Template? dialog comes up.
  10. Now you will need your DocuSign credentials to paste into the NDAKioskController class. These credentials are used to authenticate your calls to the DocuSign web service. In the DocuSign member console go to Preferences->API. At the top of the page you'll see the GUID for an Integrators Key. If you have not done so, click the Activate button next to the GUID in the Request a new Integrator's Key area. You should now see the following:

    Note the Integrators Key GUID (be sure it's the circled one), the API UserName (either the GUID or your email address will work for the userId string in the NDAKioskController class), and the API Account ID GUID. Go to your Salesforce dev site and select Setup->Develop->Apex Classes->Edit NDAKioskController. Locate the strings starting with TODO in lines 17 through 22. Replace the accountID string with the API Account ID GUID noted above. Replace the userID string with the API UserName above. Replace the password string with the password you used to login to your DocuSign dev member console. Replace the integratorsKey string with the Integrators Key circled above. Replace the templateID string with the Template ID GUID noted in step 9. Click Save. You're done!
  11. The "Here to see:" input field on the welcome page looks at your Salesforce Contacts to figure out whom to email for notification a visitor has arrived to see them. You should add a few test contacts, and include email addresses you can monitor. Without a valid email address, the "Here to see" feature will present a message saying: "The person you are here to see doesn't seem to be listed. Please notify the receptionist, then press continue".
  12. You can now try the application. Go to Setup->Develop->Pages and click on the ndawelcome Label. Replace the ID number with "apex/ndawelcome". You will be taken to your Welcome page, and you can try out the application either on your desktop, or your iPad!

Control Flow

The application consists of six pages. The NDAKioskController class determines flow from page to page. The following diagram illustrates the control flow.

Some Code Walthrough

We will concentrate on the code that is unique to the DocuSign API and how it works. The "SendNDANow" private NDAKioskController class created in step 7 implements most of this functionality. It is this method that builds an "Envelope" from the data in an NDA_Signer custom object (created in step 2) and a template (uploaded in step 9).

An Envelope is a transaction container that includes documents, recipient information, workflow, and data.

The first thing this method does is to create a "Recipient".

A Recipient is a person who receives an Envelope. This recipient can have one of several roles: signer, carbon copy recipient, editor, agent, or certified delivery.

By default, validation is "trusted" meaning the person who will sign the document is known to be the correct one. There are other levels of validation that DocuSign offers including voice identification by phone, and RSA identification. The following code makes these choices based on what was selected on the welcome page:

if (signer.validate_method__c == 'RSAID') {
	recipient.RequireIDLookup = true;
else if (signer.validate_method__c == 'PHONE') {
	recipient.RequireIDLookup = true;
	recipient.IDCheckConfigurationName = 'Phone Auth $';
	DocuSignAPI.RecipientPhoneAuthentication phoneAuth = new DocuSignAPI.RecipientPhoneAuthentication();
	phoneAuth.RecipMayProvideNumber = true;
	recipient.PhoneAuthentication = phoneAuth;
else {
	recipient.RequireIDLookup = false;

The following code informs the DocuSign web service that we wish to initiate an Embedded signing experience.

An Embedded Signing Experience means that the document to be signed will appear embedded in a web application. A Remote Signing Experience means that the document will be emailed to a recipient for signing.
// make recipient captive for embedded experience
recipient.CaptiveInfo = new DocuSignAPI.RecipientCaptiveInfo();
recipient.CaptiveInfo.ClientUserId = '1';

Next we want to use a template that is stored in your DocuSign member account (a "server-side template") as the document to be signed:

// Create object for the NDA server-side template
DocuSignAPI.TemplateReference ndaTemplate = new DocuSignAPI.TemplateReference();
ndaTemplate.Template = templateId;
ndaTemplate.TemplateLocation = 'Server';

We have some "tabs" on our template that need to be filled in from the information we entered on the ndawelcome page. Each tab has a label and a value. The following code fills these in:

// Add data for fields
DocuSignAPI.TemplateReferenceFieldDataDataValue fd1 = new DocuSignAPI.TemplateReferenceFieldDataDataValue();
fd1.TabLabel = 'Full Name 1';
fd1.Value = recipient.UserName;

DocuSignAPI.TemplateReferenceFieldDataDataValue fd2 = new DocuSignAPI.TemplateReferenceFieldDataDataValue();
fd2.TabLabel = 'Company 3';
fd2.Value = signer.Company__c;

Now we make the call to CreateEnvelopeFromTemplates. If we had not created the CaptiveInfo object above, the document would have been sent to the Recipient's email. Instead, the method returns an envelope id that can be used to get a unique session limited URL, called a "token URL" that can be used in an iframe element for an embedded signing. The code to get this URL is as follows:

DocuSignAPI.RequestRecipientTokenClientURLs clientURLs = new DocuSignAPI.RequestRecipientTokenClientURLs();

clientURLs.OnAccessCodeFailed = getPopURL() + '?Id=' + + '&event=OnAccessCodeFailed&envelopeid=' + envelopeID;
clientURLs.OnCancel = getPopURL() + '?Id=' + + '&event=OnCancel&envelopeid=' + envelopeID;
clientURLs.OnDecline = getPopURL() + '?Id=' + + '&event=OnDecline&envelopeid=' + envelopeID;
clientURLs.OnException = getPopURL() + '?Id=' + + '&event=OnException&envelopeid=' + envelopeID;
clientURLs.OnFaxPending = getPopURL() + '?Id=' + + '&event=OnFaxPending&envelopeid=' + envelopeID;
clientURLs.OnIdCheckFailed = getPopURL() + '?Id=' + + '&event=OnIdCheckFailed&envelopeid=' + envelopeID;
clientURLs.OnSessionTimeout = getPopURL() + '?Id=' + + '&event=OnSessionTimeout&envelopeid=' + envelopeID;
clientURLs.OnSigningComplete = getPopURL() + '?Id=' + + 	'&event=OnSigningComplete&envelopeid=' + envelopeID;
clientURLs.OnTTLExpired = getPopURL() + '?Id=' + + 	'&event=OnTTLExpired&envelopeid=' + envelopeID;
clientURLs.OnViewingComplete = getPopURL() + '?Id=' + + '&event=OnViewingComplete&envelopeid=' + envelopeID;

// assumes apiService = preconfigured api proxy
try {
	token = dsApiSend.RequestRecipientToken(envelopeId, recipient.captiveinfo.ClientUserId, recipient.UserName, recipient.Email, assert,clientURLs);
}  catch ( CalloutException e) {
	System.debug('Exception - ' + e );
	errMsg = 'Exception - ' + e;
	return '';
return token;

Note the series of RequestRecipientTokenClientURLs. These are callback URLs that are called by the DocuSign web service depending on the event that ended the document signing. Here we are calling the ndapop page we created to "pop" out of the iframe and send us to the ndadone page.

Resource files:


Recipe Activity - Please Log in to write a comment

I just ran it using Chrome on my iPad 3 and it works fine.  

by Ian Brown  (2013-01-18)

This works flawlessly using a desktop browser.

It is not working on my iPad 3 in Safari when I tested it.  After filling out the form and pressing Enter, it hangs on the ndaesign Visualforce page (

I followed the above steps line by line, not sure what I'm missing. Thanks if anyone has any ideas.

by Ian Brown  (2013-01-18)

Works great in the sandbox. Anyone figure out a test class for this so it can be moved to production?

by goduke150  (2012-09-25)

To answer my own question: the DocuSign interface has changed. I was trying to create a template and upload the template as a document. To upload a Template, click Manage, My Templates, Actions, Upload Template.

by Steve Gullion  (2012-03-07)

Great post, but something must have changed with DocuSign templates... when I try to upload the template to DocuSign, it tries to read it as a PDF file, (notwithstanding the XML suffix), displays the XML contents, and basically hangs. Am I missing something, or is an update needed?

by Steve Gullion  (2012-03-07)

How do we run this application ?

voted as verified by Sumit Chowdhury  (2011-10-07)

Am really stranded on deploying my application almost similar to the above from my sandbox to production environment since i don't know how to write the test methods for the used Apex Controllers. 
Anyone with ideas on how to go about it?

by Sayame  (2011-06-07)

Any guidance on how to write the test case for the above code?

by Sayame  (2011-06-06)

I want to see this Recipe.

voted as verified by NightFox  (2011-03-31)

Did verify this. It works like a charm.

voted as verified by Mike Borozdin  (2011-03-15)

 Great post!  Thanks Craig!

by Mike Borozdin  (2011-03-11)


Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.