docusign / docusign-esign-php-client

The Official Docusign PHP Client Library used to interact with the eSign REST API. Send, sign, and approve documents using this client.
https://www.docusign.com/devcenter
MIT License
198 stars 124 forks source link

BUG: Not able to get embedded signing url when not passing a client user id to the request #225

Open samuelhgf opened 3 months ago

samuelhgf commented 3 months ago

Hi, I'm using the library inside a Laravel project where I'm trying to generate the signing url for a specific signer. Before this, the envelope is created using the api as well, calling the createSenderView endpoint, passing all of the envelope definitions.

TL;DR

The createRecipientView endpoint only works passing the client_user_id correct. The same that was passed within the envelope creation endpoint (createRecipientView).


Since I'm using a template_id, I also pass the Templates Roles to the envelope definitions. Inside the templates roles I can pass the client_user_id, but if the person that is finishing the envelope deletes the signers and creates new ones even with the same data (Name and Email) the client_user_id will be null. And with this field null, when I try to get the embedded signing url, calling the createRecipientView, passing the signer's name, email and client_user_id = null returned by DocuSign, the loaded envelope does not have the signature field, seems to be in a review mode. I also tried using the user_id from DocuSign and got the same thing.

Creating the preview and send envelope url

$envelopeSigners = [
            resolve(TemplateRole::class)
                ->setRoleName('signer')
                ->setClientUserId($sender->id)
                ->setName($sender->name)
                ->setEmail($sender->email),
        ];
        $clientId = null;

        foreach ($signers as $signer) {
            if (data_get($signer, 'is_client')) {
                $clientId = data_get($signer, 'user_id');
            }

            $envelopeSigners[] = resolve(TemplateRole::class)
                ->setRoleName('signer')
                ->setClientUserId(data_get($signer, 'user_id'))
                ->setName(data_get($signer, 'name'))
                ->setEmail(data_get($signer, 'email'));
        }

        $envelopeDefinition = resolve(EnvelopeDefinition::class)
            ->setStatus('created')
            ->setTemplateId($template->template_id)
            ->setTemplateRoles($envelopeSigners);

        $customFields = [];

        $senderUserIdField = app(TextCustomField::class);
        $senderUserIdField->setName(CustomFieldsKeys::SenderUserIdKey)
            ->setShow('false')
            ->setValue(user()->id);
        $customFields[] = $senderUserIdField;

        $meetingIdFields = app(TextCustomField::class);
        $meetingIdFields->setName(CustomFieldsKeys::MeetingIdCustomFieldKey)
            ->setShow('false')
            ->setValue($meeting->id);
        $customFields[] = $meetingIdFields;

        if ($clientId) {
            $clientIdField = app(TextCustomField::class);
            $clientIdField->setName(CustomFieldsKeys::ClientIdCustomFieldKey)
                ->setShow('false')
                ->setValue($clientId);

            $customFields[] = $clientIdField;
        }

        $envelopeField = app(CustomFields::class);
        $envelopeField->setTextCustomFields($customFields);

        $envelopeDefinition->setCustomFields($envelopeField);

        try {
            $response = $this->envelopesApi
                ->createEnvelope(
                    account_id: $this->accountId,
                    envelope_definition: $envelopeDefinition,
                );

            $options = app(ReturnUrlRequest::class);
            $options->setReturnUrl(route('docusign.envelope-callback'));

            return $this->envelopesApi->createSenderView($this->accountId, $response->getEnvelopeId(), $options)->getUrl();

Creating the embedded signing url

$request = app(RecipientViewRequest::class)
            ->setAuthenticationMethod('None')
            ->setEmail($signer->email)
            ->setUserName($signer->name)
            ->setClientUserId($signer->docusign_user_id) // If that's null it never works
            ->setReturnUrl($returnUrl)
            ->setFrameAncestors([
                config('app.url'),
                config('services.docusign.signing_link_frame_ancestor'),
            ])
            ->setMessageOrigins([
                config('services.docusign.signing_link_frame_ancestor'),
            ]);

        try {

            return $this->envelopesApi
                ->createRecipientView(
                    account_id: $this->accountId,
                    envelope_id: $envelope->envelope_id,
                    recipient_view_request: $request,
                )
                ->getUrl();
karankaushik95 commented 3 months ago

Hi there,

This is the expected behaviour. To generate a recipientView without a clientUserId, you'd need to authenticate the request as the recipient. Otherwise, embedded views require a clientUserId to be set.

If you'd like for the recipients to not get modified, you can lock your senderView so that the user accessing the senderView can only access the tagger by setting the startingScreen parameter

Another way I can think of would be to use a Docusign Connect event on "envelope-sent" to check the envelope and update the recipients to have a clientUserId in place.

samuelhgf commented 3 months ago

Hi @karankaushik95, thanks for the quick reply!

Do you have some docs link that explains how to authenticate the request as the recipient?

And I didn't follow this option to set the starting screen to tagger. What exactly it does ?

And using the DocuSign Connect you mean update the envelopes signer after it as sent with their client_user_id and before creating the signing link ?