Getting started with Dropbox Sign-embedded signing using PHP
by
Dapree Doyle
January 2, 2024
16
minute read
New look, same great product! HelloSign is now Dropbox Sign.
To keep pace with the global needs of today’s business, organizations are digitizing more and more of their traditional operations. Your company probably has internal document workflows to initiate procurement processes, pay vendors, send contracts, and so on, particularly to keep things moving quickly for international partnerships or remote employees and contractors. Adding an electronic document signing solution, such as Dropbox Sign, to that workflow facilitates speed while streamlining approval processes and storing legally binding digital records of all signatures.
For example, let’s say that you’re developing a PHP web application for a talent-contracting firm; the firm would love to have an in-house solution for document signing. So far, you have a base system that allows users to upload documents to a dashboard where they can request a signature or supply one. They can preview a signature request and read the attached document right from their dashboard. The only feature left to implement is to enable users to, well, actually sign the documents.
Let’s take a look at how Dropbox Sign (formerly HelloSign) can integrate easily with this talent-contracting firm’s platform. You’ll learn how to construct a signature request using Dropbox Sign’s PHP SDK and then embed a signing flow in your application so users can sign their respective documents.
Setting up the demo documenter app
Before you move on with the tutorial, there are a handful of prerequisites you’ll need to have at the ready:
To make it easier to follow along, you can check out the tutorial’s simple web application provided in [this GitHub repository](https://github.com/rexfordnyrk/documenter). The demo app, built with Laravel, provides authentication functionalities to mimic an authenticated user and allows for basic user registration and profile editing. It also provides a simple dashboard where users can upload documents for signing, as well as review previous documents.
You can either clone this repo and work on the basic branch, or you can access the complete code for the final output of this tutorial on the main branch.
Clone the repo by executing the following command in your favorite terminal:
Create a .env file from the existing .env.example file:
cp .env.example .env
Then create an APP_KEY:
php artisan key:generate
The APP_KEY is a random string used for cryptographic operations, such as encrypting your application's user password for secure storage.
Setting up the database
To set up the database for the application, you need to create a user with the alias `documenter` who will manage a database with the alias `documenter_db`. After creating the user and the database, you’ll need to grant all database privileges to the user.
To get started, log in as root user:
Running the application
At this point, you can run the web application and make it accessible in your browser. The web application depends on both PHP and JavaScript, so you need to run servers for both languages.
Run the PHP server in a terminal at the root of your project directory:
php artisan serve
In a different terminal, run the Node.js server:
npm run dev
The application will be served on http://localhost:8000. Upon opening the application in a browser, you should see an output like the image below:
A default user was created as part of the migration seeding. This default user’s username is documenter@yopmail.com and the password is 123456. You can directly log in to the application’s dashboard using these details.
Obtaining an API key
Now let’s find out how to obtain an API key and client ID from Dropbox Sign’s dashboard.
First, you need to create a Dropbox Sign account—you can start with a free trial. After you’ve successfully created an account, walk through a simple wizard to complete your first document signing request.
To create an API key from your dashboard, click API on the dashboard’s menu, then click Generate key. A dialog asks you to define the name of the key you want to create. Give it a name like Documenter, then click Generate key once more to finish.
You should see your newly generated API key among the listed options in your dashboard.
Creating an API app
To get a client ID for your application, you need to create an API app—in this case, Documenter. Click Create Application in your Dropbox Sign dashboard or click this link.
Fill out the form’s General Information section of the form; the other sections are optional, so complete them if you like. In the General Information section, give your application a name and set the domain field to your app’s top level domain (TLD) (egexample.com). This information will be used in production for signing requests, but it won’t affect anything on development, such as your localhost.
Adding the Dropbox Sign PHP SDK and dependencies
Here, let’s add the Dropbox Sign PHP SDK to your existing application using Composer. Execute the require command in a terminal at the root of your project directory:
composer require "dropbox/sign:1.1.*"
This downloads and adds the Dropbox Sign PHP SDK to your application and also resolves and installs all its dependencies. Your output should look similar to this:
Creating environment variables for your Dropbox keys
Now you need to create two environment variables in the .env file to hold your API key and client ID. This is a recommended best practice in order to avoid exposing them by embedding them directly in your code.
Add the following lines to the end of the .env file in the root of your project directory:
Remember to replace the text after the equal sign with your API key and client ID.
Now you’re ready to include Dropbox Sign’s embedded signing functionality in your PHP application!
Creating a signing request
You have a few options for requesting signatures with Dropbox Sign:
Files: Simply sign into your application and select the files that need to be signed. Dropbox Sign automatically creates a new page at the end of your selected documents, with fields for the signatures you’ve specified. Signatories receive links via email where they can review and sign their documents.
Templates: For documents that must use a certain structure or wording, such as a standard engagement contract, you can define templates with custom fields for variable information such as the person's name, position, and salary. Again, signatories receive emails with links to review and sign the document.
File and form fields: When the core content of the document changes depending on context, such as in an internal memo, but the fields that need to be filled or signed remain the same, you can use the file and form fields option. You’ll provide the list of the fields and their coordinates when sending a request via API.
For simplicity’s sake, this tutorial uses the files method. It’s the quickest and simplest way to get started, and you can upload almost any document and immediately request a signature without a lot of extra steps in between.
Before you can create your first signature request, you need to add the required code to the app/Http/Controllers/SignatureRequestController.php file and the signature-requests/show blade template.
To get started, add the following code at the top of the SignatureRequestController.php file beneath the existing imports:
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
...
use Dropbox\Sign\Api\EmbeddedApi;
use Dropbox\Sign\Api\SignatureRequestApi;
use Dropbox\Sign\ApiException;
use Dropbox\Sign\Configuration;
use Dropbox\Sign\Model\SignatureRequestCreateEmbeddedRequest;
use Dropbox\Sign\Model\SignatureRequestGetResponse;
use Dropbox\Sign\Model\SubSignatureRequestSigner;
use Dropbox\Sign\Model\SubSigningOptions;
use SplFileObject;
...
This imports the various classes from the SDK that you’ll be using to interact with the Dropbox Sign API.
Next, you want to add a function for making an API call to create your embedded signature request. You’ll use the information from the Create Signature Request form available in the resources/views/signature-requests/create.blade.php file. All the user-submitted information will be extracted into two variables passed on to the function. The parties who need to sign are extracted into the $signatories array and the rest of the form values in the $signaturerequest object.
Add the following performDSRequest function definition as a new method in the SignatureRequestController.php file:
public function performDSRequest(Array $signatories, SignatureRequest $request){
//getting default configuration
$config = Configuration::getDefaultConfiguration();
// Configure HTTP basic authorization: api_key
$config->setUsername(env('DS_API_KEY'));
$signatureRequestApi = new SignatureRequestApi($config);
$signers = [];
for ($i = 0; $i < count( $signatories); $i++) {
//creating a new Dropbox Sign Signer
$signer = new SubSignatureRequestSigner();
//Setting Signer Properties from Signatories Specified in the form
$signer->setEmailAddress($signatories[$i]->email)
->setName($signatories[$i]->name)
->setOrder($i);
//adding signer to list (array) of signers
$signers[] = $signer;
}
//Setting option to determine how the user signs
$signingOptions = new SubSigningOptions();
$signingOptions->setDraw(true)
->setType(true)
->setUpload(true)
->setPhone(true)
->setDefaultType(SubSigningOptions::DEFAULT_TYPE_DRAW);
//Creating a Dropbox Sign Embedded signature request and assigning the necessary properties
$data = new SignatureRequestCreateEmbeddedRequest();
//using client id place in .env file
$data->setClientId(env('DS_CLIENT_ID'))
->setTitle($request->title)
->setSubject($request->title)
->setMessage($request->description)
->setSigners($signers)
->setCcEmailAddresses([
"legal@wehire.io",
])
->setFiles([new SplFileObject(storage_path('app/' . $request->document))])
->setSigningOptions($signingOptions)
->setTestMode(true);
try {
//Making API call to Dropbox Sign to create Embedded signature request and returning response
return $signatureRequestApi->signatureRequestCreateEmbedded($data);
} catch (ApiException $e) {
// if there is an error return the error
return $e->getResponseObject()->getError();
}
}
The method above sets the configuration for the SDK using the DS_API_KEY and DS_CLIENT_ID environment variables you recently added. The configuration creates a signature request API object, which will be used later to make the API request.
The behavior of the signing process is defined, allowing the user to draw, type, or upload their signature. An object is created to hold the body of the request, and the title, subjects, and message are set. These details are used to send email notifications to the cc’d email addresses included in the embedded request. Generally, embedded workflows do not provide email notifications to the signers. However, by including the cc_email_addresses parameter, notifications of the final signed document will be sent to those emails included in the request. As you can see, this example cc’s the legal team.
The files or documents to be signed are attached using the set files method, which accepts an array. However, in this case, you’re only submitting a single file.
Finally, in the try-catch block, the API request is made to Dropbox Sign, and the response is returned. If there’s an error making the request, it would be caught and returned in the catch block.
You need to call this function in the part of your application that handles the form processing—in this case, it’s the store() method inside the SignatureRequestController.php file. Paste the following code right before the $signatureRequest->signatories()->saveMany($signatories) function call:
$results = $this->performDSRequest($signatories, $signatureRequest);
if ($results instanceof SignatureRequestGetResponse) {
$signatureRequest->reference_id = $results->getSignatureRequest()->getSignatureRequestId();
$signatureRequest->save();
$signers = $results->getSignatureRequest()->getSignatures();
//looping through the signers and assigning their DS signature_id
// to the signatory to be used to generate signing page.
if (count($signers) > 1){
for ($i = 0; $i < count($signers); $i++) {
$signatories[$signers[$i]->getOrder()]->ds_signature_id = $signers[$i]->getSignatureId();
}
}else{
$signatories[0]->ds_signature_id = $signers[0]->getSignatureId();
}
}else{
return Redirect::to('/dashboard')
->with('error', 'There was an error completing your request.Please contact tech support.\n'.$results);
}
This checks to ensure that the results are a valid response obtained from the API, and extracts the signatureRequestId to be stored as a reference_id. The respective signature IDs of each signer are obtained and stored to the database. You can use these later to check the status of a signature request or download a signed file. The signature ID for individual signers is used to generate temporary unique URLs for accessing and signing the documents.
After this, you can log into your application and submit a signature request form. If this is successful, you’ll see it in your Dropbox Sign dashboard along with all requests made via API or on the platform.
Generating a signing URL
You’ll use the signature ID of each signer to obtain a temporary unique URL that allows the user to sign a document. But before you can generate a signURL, you need to know the user’s signature_id. This is returned as part of the response when you make an embedded signature request.
The `show()` method of the SignatureRequestController.php file handles all HTTP requests to view the details of a specific `SignatureRequest` in this application. The ID specified through the URL fetches that SignatureRequest record from the database, which is in turn used to populate the frontend.
Paste the following snippet right before the return statement of the show() method in the SignatureRequestController.php file:
//getting default configuration
$config = Configuration::getDefaultConfiguration();
// Configure HTTP basic authorization: api_key
$config->setUsername(env('DS_API_KEY'));
$embeddedApi = new EmbeddedApi($config);
//obtaining signing id if the current user is a signatory
$signatory = $signatureRequest->signatories->where('email', Auth::user()->email)->first();
if ($signatory != null){
//if the current user is a valid signatory then generate embedded sign url using their signature_id
try {
$result = $embeddedApi->embeddedSignUrl($signatory->ds_signature_id);
$signatureRequest['sign_url']=$result->getEmbedded()->getSignUrl();
} catch (ApiException $e) {
$error = $e->getResponseObject();
return view('signature-requests.show', compact('signatureRequest'))
->with('error', 'There was an error completing your request. Please contact tech support.\n'.$error);
}
}
This snippet initializes the SDK and an EmbeddedAPI object. If the current user is recognized as a signatory on the request, their signature ID is extracted and used to obtain a signURL for that SignatureRequest. The URL string is then passed to the frontend to be used later.
Obtaining and installing the JavaScript library
How you obtain the library depends on what frontend technologies you’re using for your application. Dropbox Sign offers a way to use their frontend library through npm, through a CDN, and through GitHub as a script.
Since you may not be able to guarantee the availability of a CDN, you can download the plugin from the releases section of the GitHub repo. This is what we’ll do for this tutorial. Download the library into a publicly accessible directory of the application, specifically the public directory in the root of the project directory.
Now you can open the resources/views/signature-requests/show.blade.php file. This file contains the code that shows the details of a single signature request. Paste the following snippet at the bottom of the file, right before the closing x-app-layout tag.
This snippet first declares and assigns the client ID you obtained from the dashboard earlier, as well as the signURL provided from the backend. A simple function is created in JavaScript that initializes the HelloSign library with the URL, the client ID, and two other parameters to tell the HelloSign API that this is a test scenario and to ignore domain verification.
Please note that you’ll need to skip domain verification when testing on a domain different from the domain assigned to the client ID being used.
Finally, add a Sign Document button to the page by pasting this code right beneath the Back button:
This button only appears if the user is a signatory on the current document being viewed.
Once a user clicks Sign Document, they see a modal containing an iframe with the document to sign. Since you’re working with a free account in test mode, you’ll receive a notice that this document is not legally binding, as in the image below.
Click OK, and Dropbox Sign appends a signature page to the end of the document where the user can complete signing.
Congratulations! You’ve successfully integrated embedded signing into your application with Dropbox Sign.
Getting ready for production
Now that document signing is finally working within your PHP application, let’s quickly review a few things to get your application ready for production.
You might have noticed a disclaimer after you generated your client ID earlier.
Before you can go live, Dropbox Sign needs to first approve your application for compliance with e-signature regulatory policies.
After approval, ensure that your application is hosted on a registered domain owned by your organization, complete with SSL certificates, and ensure you are on the correct Dropbox Sign API plan. (Embedded workflows start at the standard API plan level.)
Then you’re ready to go live with your application!
Conclusion
If you’ve made it this far, document signing shouldn’t be a problem for your organization anymore.
You know how to implement document signing via the files method using the Dropbox Sign SDK. Using Composer, you installed and imported the SDK package and dependencies into a sample PHP application, and you configured the SDK for making requests. Using the Dropbox Sign PHP SDK, you’ve created your first signature request and generated an embedded signing URL for authorized users to easily sign their respective documents.
With just a few minor steps, your application can serve your whole organization and solve all of its document-signing challenges!
Stay in the loop
Done! Please check your inbox.
Thank you! Thank you for subscribing!
Lorem ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.