DocuSign Embedded signing in Core PHP, CodeIgniter 4, Laravel 8

DocuSign Embedded Sign

DocuSign Embedded Signing in Core PHP, CodeIgniter 4 or Laravel 8: I will show you step by step guide to help you in quick start. Here, I mentioned every detail that you need to handle bugs errors and many more things.

Today we will see how we can do an embedded signing with DocuSign in Core PHP or any Other. If you are reading my blog which means you also want to integrate DocuSign with your Application. Please follow the below instruction to integrate DocuSign in one shot.

Step: 1 Create a developer account on DocuSign

I Know, You that stuff very well and you already your DocuSign developer account. But dude let me clear few things for you that will help you to understand the DocuSign API and structure.

docusign Api Credentials

Credits: codeHunger

Here, You need to create APP Like DemoApp for your project. Account id, Integration key ( Client_id / ds_client_id), Secret Key and Refer Url. These 3 things are very necessary.

Suggestion: I personally Suggest you to create ds_config.php file with all configuration constant to handle the whole API.

ds_config file for DocuSign

DocuSign App Details

Step: 2 Create an DocuSign Folder on Xampp.

create a folder in your Xampp or Server. here, I also suggest, test on xampp and than use composer. if you don’t know about don’t worry just follow my steps.

First install composer from https://getcomposer.org/download/. than you need to install DocuSign Library using Command.

after installing composer, open your in the right folder for docusign.

Step: 3 Install DocuSign Package

Composer require docusign/esign-client

 

docusign API Directory or folder
After this Command, you have vendor folder which contain packages, src folder which contain our Base Class which handle all API, and doc folder contain PDF file which need to signature. and index.php file is base file which can be Laravel routes, CodeIgniter routes or controller,  or any file which handle routes. and ds_config.php as i already told you above.

suggestion: you can use .env in replacement of ds_config if you are using Laravel or any other framework.

 

Step: 4 Collect all code and Files as Given below

index.php file code:

<?php 

require_once dirname(__FILE__). '/ds_config.php';
require_once dirname(__FILE__). '/src/DocuSignController.php';

$docuSign = new DocuSignController();

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

$authData = @$_SESSION['authData'];
if(@$_GET['page']=='connect'){
   $docuSign->connect(); 
}elseif(@$_GET['page']=='sign'){

   $docuSign->signDocument();
}
else{
  if(@$_GET['code'] && ( !array_key_exists('authData',$_SESSION) || property_exists($authData,'error') )){
        $docuSign->callback();
  }
  //session_destroy();
  $docuSign->index();
}
?>

Src folder code and structure:

Here in src folder, we have 2 files one is index.php ( view ) and another DocuSignController.php Class which contain all API. In CodeIgniter you can use it as custom library, in Laravel you can use it as Controller or Service.

So, Here Index.php ( view ) code:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Docusign Integration Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
  <div class="container">
   <div class="card">
    <div class="card-header">
        PHP and DocuSIgn
      </div>
      <div class="card-body">
        <h5 class="card-title">Docusign </h5>
        <p class="card-text">Click the button below to connect your appication with docusign</p>
        <?php
        if (@$_SESSION['message'] =='success'){
        ?>
          <a href="index.php?page=sign" class="btn btn-primary">Click to sign document</a>
        <?php
        }
        else{ 
        ?>
          <a href="index.php?page=connect" class="btn btn-primary">Connect Docusign</a>
        <?php
         }
        ?>
  </div>
    </div>
  </div>
</body>
</html>

DocuSignController.php class code:

<?php
require_once dirname(__DIR__). '/vendor/autoload.php';
use DocuSign\eSign\Configuration;
use DocuSign\eSign\Api\EnvelopesApi;
use DocuSign\eSign\Client\ApiClient;

class DocuSignController {        
    /** hold config value */
    private $config;
    private $signer_client_id = 1000; # Used to indicate that the signer will use embedded
    /** Specific template arguments */
    private $args;

    public function index(){
      require_once dirname(__FILE__).'/views/index.php';    
    }

    
    /**
     * Connect your application to docusign
     *
     * @return url
     */
    public function connect()
    {
        try {
            $params = [
                'response_type' => 'code',
                'scope' => 'signature',
                'client_id' => $GLOBALS['DS_CONFIG']['ds_client_id'],
                'redirect_uri' =>$GLOBALS['DS_CONFIG']['app_url'],
            ];
            $queryBuild = http_build_query($params);
            $url = "https://account-d.docusign.com/oauth/auth?";
            $botUrl = $url . $queryBuild;
            header('Location:'.$botUrl);
           
        } catch (Exception $e) {
            $_SESSION['message'] = 'error';
            return false;
        }
    }
    public function callback()
    {
        $code = $_GET['code'];
        $client_id =  $GLOBALS['DS_CONFIG']['ds_client_id'];
        $client_secret =  $GLOBALS['DS_CONFIG']['ds_client_secret'];
        $integrator_and_secret_key = "Basic " . utf8_decode(base64_encode("{$client_id}:{$client_secret}"));
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,  $GLOBALS['DS_CONFIG']['authorization_server'].'/oauth/token');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        $post = array(
            'grant_type' => 'authorization_code',
            'code' => $code,
        );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        $headers = array();
        $headers[] = 'Cache-Control: no-cache';
        $headers[] = "authorization: $integrator_and_secret_key";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        }

        curl_close($ch);
        $decodedData = json_decode($result);
        $_SESSION['authData'] = $decodedData;
        $_SESSION['message'] = 'success';
        return true;
    }
    
    public function signDocument()
    {       
      try{
        $this->args = $this->getTemplateArgs();
        $args = $this->args;
        $envelope_args = $args["envelope_args"];
        
        # Create the envelope request object
        $envelope_definition = $this->make_envelope($args["envelope_args"]);
        $envelope_api = $this->getEnvelopeApi();
      
        # Call Envelopes::create API method
        # Exceptions will be caught by the calling function
        
        $api_client = new \DocuSign\eSign\client\ApiClient($this->config);
        $envelope_api = new \DocuSign\eSign\Api\EnvelopesApi($api_client);
        
        $results = $envelope_api->createEnvelope($args['account_id'], $envelope_definition);
       
        $envelope_id = $results->getEnvelopeId();        
        $authentication_method = 'None'; # How is this application authenticating
        # the signer? See the `authenticationMethod' definition
        # https://developers.docusign.com/esign-rest-api/reference/Envelopes/EnvelopeViews/createRecipient
        
        $recipient_view_request = new \DocuSign\eSign\Model\RecipientViewRequest([
            'authentication_method' => $authentication_method,
            'client_user_id' => $envelope_args['signer_client_id'],
            'recipient_id' => '1',
            'return_url' => $envelope_args['ds_return_url'],
            'user_name' => 'SuryaPratap', 'email' => 'soroutlove1996@gmail.com'
        ]);
        $results = $envelope_api->createRecipientView($args['account_id'], $envelope_id,$recipient_view_request);
        return header('Location:'.$results['url']);
        } catch (Exception $e) {
            echo "<pre>";
            print_r($e);
        }
        
    }

    private function make_envelope($args)
    {   
        
        $filename = 'World_Wide_Corp_lorem.pdf';
        $demo_docs_path = dirname(__DIR__)."/doc/".$filename;
        $arrContextOptions=array(
            "ssl"=>array(
                "verify_peer"=>false,
                "verify_peer_name"=>false,
            ),
        );  
        $content_bytes = file_get_contents($demo_docs_path,false, stream_context_create($arrContextOptions));
        // dd($content_bytes);
        $base64_file_content = base64_encode($content_bytes);
        // dd($base64_file_content);
        # Create the document model
        $document = new \DocuSign\eSign\Model\Document([# create the DocuSign document object
        'document_base64' => $base64_file_content,
            'name' => 'Example document', # can be different from actual file name
            'file_extension' => 'pdf', # many different document types are accepted
            'document_id' => 1, # a label used to reference the doc
        ]);
        # Create the signer recipient model
        $signer = new \DocuSign\eSign\Model\Signer([# The signer
        'email' => 'soroutlove1996@gmail.com', 'name' => 'SuryaPratap',
            'recipient_id' => "1", 'routing_order' => "1",
            # Setting the client_user_id marks the signer as embedded
            'client_user_id' => $args['signer_client_id'],
        ]);
        # Create a sign_here tab (field on the document)
        $sign_here = new \DocuSign\eSign\Model\SignHere([# DocuSign SignHere field/tab
        'anchor_string' => '/sn1/', 'anchor_units' => 'pixels',
            'anchor_y_offset' => '10', 'anchor_x_offset' => '20',
        ]);
        # Add the tabs model (including the sign_here tab) to the signer
        # The Tabs object wants arrays of the different field/tab types
        $signer->settabs(new \DocuSign\eSign\Model\Tabs(['sign_here_tabs' => [$sign_here]]));
        # Next, create the top level envelope definition and populate it.
        $envelope_definition = new \DocuSign\eSign\Model\EnvelopeDefinition([
            'email_subject' => "Please sign this Broker Agreement document - MortgageStreet",
            'documents' => [$document],
            # The Recipients object wants arrays for each recipient type
            'recipients' => new \DocuSign\eSign\Model\Recipients(['signers' => [$signer]]),
            'status' => "sent", # requests that the envelope be created and sent.
        ]);

        return $envelope_definition;
    }

    /**
     * Getter for the EnvelopesApi
     */
    public function getEnvelopeApi(): EnvelopesApi
    {   
        $this->config = new Configuration();
        $this->config->setHost($this->args['base_path']);
        $this->config->addDefaultHeader('Authorization', 'Bearer ' . $this->args['ds_access_token']);    
        $this->apiClient = new ApiClient($this->config);
        return new EnvelopesApi($this->apiClient);
    }
    /**
     * Get specific template arguments
     *
     * @return array
     */
    private function getTemplateArgs()
    {   
        $envelope_args = [
            'signer_client_id' => $this->signer_client_id,
            'ds_return_url' => $GLOBALS['DS_CONFIG']['app_url']."?status=success",
        ];

        $args = [
            'account_id' =>  $GLOBALS['DS_CONFIG']['account_id'],
            'base_path' => $GLOBALS['DS_CONFIG']['api_url'],
            'ds_access_token' => $_SESSION['authData']->access_token,
            'envelope_args' => $envelope_args
        ];
        return $args;
      }

} // end of class

Note: You must have to add callback URL in your docusign , to get your  application get authenticated.

See the below image.

Step-9 Test the integration

 

DocuSign Embedded Signing in PHPClick on connect DocuSign, you will redirect to DocuSign’s official website where they told you to enter your DocuSign email and password, after giving your credentials you will come back to your application with the below image.

 

DocuSign Embedded Signing

After connect, if everything is correct than you will get code variable in url. and than click on sign document. after this you need to authorized DocuSign with admin account details.

DocuSign Embedded Signing

DocuSign Embedded Signing
DocuSign Embedded Signing

 

I hope, this blog helps you to install docuSign. at time i was so confused with docuSign documentation and git code examples. but now you have everything.

 

You can also download DocuSign API code from my Github

Please fix the errors above and try to submit again

Loading

Related Posts

Leave a reply


This site uses Akismet to reduce spam. Learn how your comment data is processed.