From the Trenches: Signing in Salesforce with the Apex Toolkit

Developers working with the DocuSign Apex Toolkit often contact DocuSign Developer Support for help with embedding a DocuSign envelope signing session in Salesforce. Often the problem does not stem from the code they are writing, but from their attempt to apply the wrong solution to the use case they are trying to enable.

Start by thinking through the use cases

Scenario 1: A Salesforce user, who is also a DocuSign user (commonly this user is a seller) is logged into Salesforce. They initiate a DocuSign envelope which they also need to sign. They can sign in an embedded session in Salesforce.

When a Salesforce user who is also a DocuSign user, as listed in the DocuSign Apps Launcher’s user page, initiates the Apex code to send an envelope, they will authenticate to DocuSign as themselves and they will be the sender of record for the envelope. If this user is also a signer of the envelope and it is their turn to sign based on the routing order, the user can sign the envelope while logged into Salesforce in an embedded DocuSign signing page in the Salesforce session.

Scenario 2: A Salesforce Experience Cloud (Community) user, who is not a DocuSign user, initiates an envelope and needs to sign.

Community users are often your customers and you may want to give them a button in the Experience Cloud to allow them to initiate a contract, application, or other agreement for signature. To support this use case, the community needs to have DSSender permissions in Salesforce. In addition, in the DocuSign Apps Launcher settings, you need to have chosen an eSignature System Sender. The envelope sent in this scenario will be sent by the system sender, who is the Salesforce user making Apex calls and the DocuSign user making the callouts (API calls to DocuSign). The embedded signing ceremony enables the community user to sign within Salesforce, and the DocuSign Certificate of Completion reflects that your customer, the community user who initiated the agreement, signed the envelope.

The Apex and JavaScript code, as well as videos to create embedded signing, is available at How to use embedded signing on the DocuSign Developer Center.

Scenario 3: Your Salesforce org contains a community of brokers. These brokers are in the presence of a customer. The brokers need to initiate an agreement and witness the signing by the customer.

DocuSign calls this use case In Person Signing. A prerequisite for In Person Signing is that the host of the signing must be a DocuSign user. The host does not have to be a DocuSign user in the DocuSign Apps Launcher. If they are, the envelope is sent from the broker; if not, the envelope is sent from the System Sender. The community of brokers would need to be assigned the DSSender permission in Salesforce.

In Person Signing is not available as an embedded session in Salesforce. In this scenario, the envelope is initiated from Salesforce with the Apex Toolkit, but the signing is initiated from a link in the email sent by DocuSign to the host.

To create an In Person Signer in your Apex code, you need to use the Recipient constructor method. In the example below, the broker Green Beard is the host of the In Person Signing session, and the customer is Snow Beard, a contact in Salesforce.

public static String sendWithInPerson()
{  
    Opportunity myOpportunity = [SELECT Id FROM Opportunity WHERE Name = 'Refit After Battle' LIMIT 1];
    
    // Create an empty envelope with Opportunity ID as the source ID
    dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(new dfsle.Entity(myOpportunity.Id));
    
    // Find your contact to add; this is your customer
    Contact myContact = [SELECT Id, Name, Email FROM Contact WHERE Name = 'Snow Beard' LIMIT 1];       
    
    dfsle.Recipient InPerson = new dfsle.Recipient(
        null, // The ID of the associated dfsle__Recipient__c record; optional
        'inPersonSigner', //Type of recipient
        2, // Sequence
        2, // Routing order: must match the routing order on the server template if you’re using one
        new dfsle.Recipient.Role('Customer',null), // Role; used to match role name on template; case-sensitive
        myContact.Name, // inPerson Recipient name
        myCOntact.Email, // inPerson Recipient Email
        null, // Signing group; not allowed for In Person Signing
        '', // Phone; optional
        // Don't need recipient authentication for In Person Signing because by default DocuSign requires the
        // host to login to complete signing, but you can add it with the line below:
        // new dfsle.Recipient.Authentication(null, true, new List<String>{'14785xxxx'}),
        // Authentication: may need to adjust this; can be null
        Null, // No authentication
        null, // Note; optional
        null, // EmailSettings; optional
        'Green Beard', // Host name; name of the host for InPerson Signing
        'host@example.com', // Host email: email of the host In Person Signing
        false, // Sign Now: set to true for embedded signing. Does not apply to In Person Signing
        null, // Source: The Salesforce source object for the recipient; optional
        false, // readOnly: whether this recipient may be modified. Used with DocuSign templates
        false); // required: whether this recipient is required. Used with DocuSign templates
   
    // Add recipient to the envelope
    myEnvelope = myEnvelope.withRecipients(new List<dfsle.Recipient> { InPerson });    
    
    // myTemplateId contains the DocuSign ID of the DocuSign template
    dfsle.UUID myTemplateId = dfsle.UUID.parse('a87c6c6c-59ca-4518-9ead-xxxxxxxxxxxx'); // Geoff test template
    
    // Create a new document for the envelope
    dfsle.Document myDocument = dfsle.Document.fromTemplate(
        myTemplateId, // Template ID in dfsle.UUID format
        'myTemplate'); // Name of the template
    
    myEnvelope = myEnvelope.withDocuments(new List<dfsle.Document> { myDocument });
    
    // Send the envelope
    myEnvelope = dfsle.EnvelopeService.sendEnvelope(
        myEnvelope, // The envelope to send
        true); // Envelope status: send or draft; true = send
    
    System.debug(myEnvelope.Id);
    return myEnvelope.Id;    
}

For more details on In Person Signing, see: How to send an envelope to an In Person Signer.

One thing to note about In Person Signing is that after the host passes the device to the customer to sign, the customer is prompted either to enter an email or download the document and then pass control back to the host. The host is then required to log in to DocuSign to complete the envelope. This added security measure is the default behavior. The default can be changed by editing the Signing Resource file. Change the value of DocuSign_InPersonSuppressLogin to true. The XML would be:

<data name="DocuSign_InPersonSuppressLogin">true</data>

The Apex Toolkit gives you powerful methods for initiating agreements and signing the agreements, both within Salesforce and from a link sent by DocuSign to an email address. By thinking through your use cases and choosing the right example code to follow, you can get your sellers and customers signing via DocuSign in Salesforce.

Additional resources

Geoff Pfander
Author
Geoff Pfander
Senior Developer Support Engineer
Published