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
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:
POST {baseUrl}/v2.1/accounts/{accountId}/envelopes
{
"templateId": "[TEMPLATE ID]",
"templateRoles": [
{
"email": "[RECIPEITN EMAIL]",
"name": "[RECIPEITN NAME]",
"roleName": "[ROLE NAME]"
}
],
"status": "created"
}
GET {baseUrl}/v2.1/accounts/{accountId}/identity_verification
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]"
}
]
}
]
}
}
]
}
PUT {baseUrl}/v2.1/accounts/{accountId}/envelopes/{envelopeId}
{"status": "sent"}