Search code examples
docusignapidocusign-sdk

DocuSign : Add phone verification to envelope generated from a template


I am in the process of creating an integrated signature flow on our website via DocuSign PHP API.

I am trying to adapt this working example that create an envelope from a template located on my DocuSign account and populate the tabs with data from my session. This part is working.

I'm facing some difficulty to add phone verification according to : https://developers.docusign.com/docs/esign-rest-api/how-to/phone-auth/

Now, I have set up a phone verification for the first signer on my template in my DocuSign account, and it seems something is wrong with my added code because, when I click on the button that generate the enveloppe, I'm stuck on the loading page of the https://verify-d.docusign.net/ChooseMethod url which is the URL where Docusign will make the phone authentication. I see an error 500 on this page, and the page is loading for infinite.

So, I guess there is something wrong with my work trying to add the phone verification to my function : So here is my EmbedSigningService.php : (I have commented with "Elements added" so you can see my failed test)

<?php

namespace DocuSignSrc\Services;

use DocuSign\eSign\Client\ApiException;
use DocuSign\eSign\Model\Document;
use DocuSign\eSign\Model\EnvelopeDefinition;
use DocuSign\eSign\Model\Recipients;
use DocuSign\eSign\Model\Signer;
use DocuSign\eSign\Model\SignHere;
use DocuSign\eSign\Model\TemplateRole;
use DocuSign\eSign\Model\Tabs;
use DocuSignSrc\Services\SignatureClientService;


use DocuSign\eSign\Model\RecipientIdentityVerification;
use DocuSign\eSign\Model\RecipientPhoneNumber;
use DocuSign\eSign\Model\RecipientIdentityPhoneNumber;
use DocuSign\eSign\Model\RecipientIdentityInputOption;


class EmbeddedSigningService
{
    /**
     * Do the work of the example
     * 1. Create the envelope request object
     * 2. Send the envelope
     * 3. Create the Recipient View request object
     * 4. Obtain the recipient_view_url for the embedded signing
     *
     * @param  $args array
     * @param SignatureClientService $clientService
     * @return array ['redirect_url']
     */
    # ***DS.snippet.0.start
    public static function worker(array $args, SignatureClientService $clientService): array
    {
        # 1. Create the envelope request object
        $envelope_definition = EmbeddedSigningService::make_envelope($args["envelope_args"], $args["template_id"], $clientService);
        $envelope_api = $clientService->getEnvelopeApi();

        # 2. call Envelopes::create API method
        # Exceptions will be caught by the calling function
        try {
            $envelopeSummary = $envelope_api->createEnvelope($args['account_id'], $envelope_definition);
        } catch (ApiException $e) {
            $clientService->showErrorTemplate($e);
            exit;
        }
        $envelope_id = $envelopeSummary->getEnvelopeId();

        # 3. Create the Recipient View request object
        $authentication_method = 'None'; # How is this application authenticating
        # the signer? See the `authentication_method' definition
        # https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopeviews/createrecipient/
        $recipient_view_request = $clientService->getRecipientViewRequest(
            $authentication_method,
            $args["envelope_args"]
        );

        # 4. Obtain the recipient_view_url for the embedded signing
        # Exceptions will be caught by the calling function
        $viewUrl = $clientService->getRecipientView($args['account_id'], $envelope_id, $recipient_view_request);

        return ['envelope_id' => $envelope_id, 'redirect_url' => $viewUrl['url']];
    }

    /**
 *  Creates envelope definition
 *  Parameters for the envelope: signer_email, signer_name, signer_client_id
 *
 * @param  $args array
 * @param  $template_id string
 * @return EnvelopeDefinition -- returns an envelope definition
 */
public static function make_envelope(array $args, string $template_id, SignatureClientService $clientService): EnvelopeDefinition
{

    $accounts_api = $clientService->getAccountsApi();
        $accounts_response = $accounts_api->getAccountIdentityVerification($_SESSION['ds_account_id']);
        
        // *************** Elements added below
        $workflows_data = $accounts_response->getIdentityVerification();
        $workflow_id = '';
        foreach ($workflows_data as $workflow) {
            if ($workflow['default_name'] == 'Phone Authentication')
                $workflow_id = $workflow['workflow_id'];  
        }
        
        $phoneNumber = new RecipientIdentityPhoneNumber;
        $phoneNumber->setCountryCode($args['phone_country_code']);
        $phoneNumber->setNumber($args['phone_number']);

        $inputOption = new RecipientIdentityInputOption;
        $inputOption->setName('phone_number_list');
        $inputOption->setValueType('PhoneNumberList');
        $inputOption->setPhoneNumberList(array($phoneNumber));

        $identityVerification = new RecipientIdentityVerification;
        $identityVerification->setWorkflowId($workflow_id);
        $identityVerification->setInputOptions(array($inputOption));
        // ***************** End elements added


    $envelope_definition = new EnvelopeDefinition([
        'status' => 'sent',
        'template_id' => $template_id,
        'template_roles' => [
            new TemplateRole([
                'email' => $args['signer_email'],
                'name' => $args['signer_name'],
                'role_name' => 'Client',
                'client_user_id' => $args['signer_client_id'],
                'tabs' => $args['tabs'],
                // ***************  ELement added below
                'identity_verification' => $identityVerification
             
            ])
        ]
    ]);

    return $envelope_definition;
}

    # ***DS.snippet.0.end
}

And here is my function that I call to generate all of this :

<?php 
function embedSigning()
{


    $signer_name = 'John Doe';
    $signer_email = 'my@email.com'; // Anonymated here
    $myphonenumber= '0000000'; //Anonymated for sharing here but format is correct
    $signer_client_id = 1000; # Used to indicate that the signer will use embedded
    $envelope_args = [
        'signer_email' => $signer_email,
        'signer_name' => $signer_name,
        'phone_number' => $myphonenumber,
        'phone_country_code' => '33',
        'signer_client_id' => $signer_client_id,
        'tabs' => [
            'textTabs' => [
                [
                    'tabLabel' => 'TAB_text_to_prefill', // Label de l'onglet dans le modèle
                    'value' => $_SESSION['My-prefill-session-content'], // Valeur à insérer dans l'onglet
                ]
            ],
        ],
        'ds_return_url' => $GLOBALS['DS_CONFIG']['app_url'] . '/process-signature.php?page=embed-signing-return',
        'template_id' => 'xxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxx', // Anonymated here for sharing
    ];

    $args = [
        'account_id' => $_SESSION['ds_account_id'],
        'base_path' => $_SESSION['ds_base_path'],
        'ds_access_token' => $_SESSION['ds_access_token'],
        'template_id' => 'xxxxx-xxxxx-xxxxx-xxxxxx-xxxxxxx', // Spécifiez l'ID du modèle à utiliser
        'envelope_args' => $envelope_args
    ];

    $clientService = new SignatureClientService($args);


    $envelopeIdAndReturnUrl = EmbeddedSigningService::worker(
        $args,
        $clientService
    );
    if ($envelopeIdAndReturnUrl) {
        $_SESSION['envelope_id'] = $envelopeIdAndReturnUrl['envelope_id'];
        # Redirect the user to the embedded signing
        # Don't use an iFrame!
        # State can be stored/recovered using the framework's session or a
        # query parameter on the returnUrl (see the make recipient_view_request method)
        header('Location:' . $envelopeIdAndReturnUrl["redirect_url"]);
        exit();
    } else {
        die('$envelopeIdAndReturnUrl === false, censé ne jamais arriver');
    }
}

As you can see, I anonymized some variables, but without this adaptation to phone verification, everything works.

Thank you for your help !

#DocuSignAPI


Solution

  • I got an answer from the DocuSign support, so, for anyone who reach this question here is the answer : (+ You'll have more details on this blog post: https://www.docusign.com/blog/developers/using-identity-verification-templates )

    Unfortunately, it is not possible to send the phone authentication from a template within template roles. A workaround for this issue is:

    1. create a draft from a template

    POST {baseUrl}/v2.1/accounts/{accountId}/envelopes

    {
      "templateId": "[TEMPLATE ID]",
      "templateRoles": [
        {
          "email": "[RECIPEITN EMAIL]",
          "name": "[RECIPEITN NAME]",
          "roleName": "[ROLE NAME]"
        }
      ],
      "status": "created"
    }
    
    1. Get the phone authentication workflow ID (https://developers.docusign.com/docs/esign-rest-api/reference/accounts/identityverifications/list/)

    GET {baseUrl}/v2.1/accounts/{accountId}/identity_verification

    1. and then update the recipient with the identityVerification information (updateRecipients API: https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/enveloperecipients/update/)

    PUT {baseUrl}/v2.1/accounts/{accountId}/envelopes/{envelopeId}/recipients

    {
      "signers": [
        {
          "recipientId": "[RECIPEITN ID]",
          "identityVerification": {
            "workflowId": "[Workflow ID retrievd from step2]",
            "steps": null,
            "inputOptions": [
              {
                "name": "phone_number_list",
                "valueType": "PhoneNumberList",
                "phoneNumberList": [
                  {
                    "countryCode": "[COUNTRY CODE]",
                    "number": "[PHONE NUMBER]"
                  }
                ]
              }
            ]
          }
        }
      ]
    }
    
    1. Send the envelope with the updateEnvelopes API(https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/update/)

    PUT {baseUrl}/v2.1/accounts/{accountId}/envelopes/{envelopeId}

    {"status": "sent"}